[committed] c++: Fix constexpr if and braced functional cast.
diff mbox series

Message ID 20200212234250.11088-1-jason@redhat.com
State New
Headers show
Series
  • [committed] c++: Fix constexpr if and braced functional cast.
Related show

Commit Message

Jason Merrill Feb. 12, 2020, 11:42 p.m. UTC
While partially instantiating a generic lambda, we can encounter pack
expansions or constexpr if where we can't actually do the substitution
immediately, and instead remember a partial instantiation context
in *_EXTRA_ARGS.  This includes any local_specializations used in the
pattern or condition.  In this testcase our tree walk wasn't finding the use
of i because we weren't walking into the type of a CONSTRUCTOR.  Fixed by
moving the code for doing that from find_parameter_packs_r into
cp_walk_subtrees.

Tested x86_64-pc-linux-gnu, applying to trunk.

2020-02-11  Jason Merrill  <jason@redhat.com>

	PR c++/92583
	PR c++/92654
	* tree.c (cp_walk_subtrees): Walk CONSTRUCTOR types here.
	* pt.c (find_parameter_packs_r): Not here.
---
 gcc/cp/pt.c                                   |  3 ---
 gcc/cp/tree.c                                 |  5 ++++
 gcc/testsuite/g++.dg/cpp0x/nondeduced7.C      |  2 +-
 .../g++.dg/cpp1z/constexpr-if-lambda3.C       | 24 +++++++++++++++++++
 4 files changed, 30 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda3.C


base-commit: 1cd9bef89ef25b3fd506cedbc82e8bc00ff56fa8

Comments

Jason Merrill Feb. 15, 2020, 1:27 p.m. UTC | #1
On 2/13/20 12:42 AM, Jason Merrill wrote:
> While partially instantiating a generic lambda, we can encounter pack
> expansions or constexpr if where we can't actually do the substitution
> immediately, and instead remember a partial instantiation context
> in *_EXTRA_ARGS.  This includes any local_specializations used in the
> pattern or condition.  In this testcase our tree walk wasn't finding the use
> of i because we weren't walking into the type of a CONSTRUCTOR.  Fixed by
> moving the code for doing that from find_parameter_packs_r into
> cp_walk_subtrees.
> 
> Tested x86_64-pc-linux-gnu, applying to trunk.
> 
> 2020-02-11  Jason Merrill  <jason@redhat.com>
> 
> 	PR c++/92583
> 	PR c++/92654
> 	* tree.c (cp_walk_subtrees): Walk CONSTRUCTOR types here.
> 	* pt.c (find_parameter_packs_r): Not here.

Another place that is redundant with the code in cp_walk_subtrees:

Patch
diff mbox series

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c2d3a98b1c5..6e7f4555da8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3924,9 +3924,6 @@  find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
     case TEMPLATE_DECL:
       if (!DECL_TEMPLATE_TEMPLATE_PARM_P (t))
 	return NULL_TREE;
-      gcc_fallthrough();
-
-    case CONSTRUCTOR:
       cp_walk_tree (&TREE_TYPE (t),
 		    &find_parameter_packs_r, ppd, ppd->visited);
       return NULL_TREE;
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index eb540f851ee..736ef6fe667 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -5024,6 +5024,11 @@  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
       *walk_subtrees_p = 0;
       break;
 
+    case CONSTRUCTOR:
+      if (COMPOUND_LITERAL_P (*tp))
+	WALK_SUBTREE (TREE_TYPE (*tp));
+      break;
+
     case TRAIT_EXPR:
       WALK_SUBTREE (TRAIT_EXPR_TYPE1 (*tp));
       WALK_SUBTREE (TRAIT_EXPR_TYPE2 (*tp));
diff --git a/gcc/testsuite/g++.dg/cpp0x/nondeduced7.C b/gcc/testsuite/g++.dg/cpp0x/nondeduced7.C
index a8aa073c57e..eb5d5faf493 100644
--- a/gcc/testsuite/g++.dg/cpp0x/nondeduced7.C
+++ b/gcc/testsuite/g++.dg/cpp0x/nondeduced7.C
@@ -2,5 +2,5 @@ 
 // { dg-do compile { target c++11 } }
 
 template<typename, int> struct A;
-template<typename T> struct A<T, T{}> {}; // { dg-error "partial specialization" }
+template<typename T> struct A<T, T{}> {}; // { dg-error "partial specialization|involves template parameter" }
 A<int, 0> a;
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda3.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda3.C
new file mode 100644
index 00000000000..34615f71ee2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda3.C
@@ -0,0 +1,24 @@ 
+// PR c++/92583
+// { dg-do compile { target c++17 } }
+
+template <int> struct a {
+  constexpr operator int() { return 42; }
+};
+template <typename> using b = int;
+template <typename d, d> struct e {};
+template <typename d, d g> using h = e<d, __integer_pack(g)...>;
+template <typename j, typename k, k... index> void apply(j f, e<k, index...>) {
+  (f(a<index>{}), ...);
+}
+template <auto l, typename j> void m(j f) {
+  using k = b<decltype(l)>;
+  using n = h<k, l>;
+  apply(f, n{});
+}
+template <int, int c> void o() {
+  auto p = [](auto i) {
+    if constexpr (a<i>{}) ;
+  };
+  m<c>(p);
+}
+auto q() { o<0, 1>; }