PR c++/85200 - ICE with constexpr if in generic lambda.
authorJason Merrill <jason@redhat.com>
Thu, 5 Apr 2018 14:20:53 +0000 (10:20 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 5 Apr 2018 14:20:53 +0000 (10:20 -0400)
* pt.c (extract_locals_r): Don't record the local specs of variables
declared within the pattern.

From-SVN: r259127

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp1z/constexpr-if19.C [new file with mode: 0644]

index 4ae78f73b2bdceab927381ddb5911f0d27799772..99ec3ea171e745ef65195d4e6a1a73d8c8b89d2a 100644 (file)
@@ -1,3 +1,9 @@
+2018-04-05  Jason Merrill  <jason@redhat.com>
+
+       PR c++/85200 - ICE with constexpr if in generic lambda.
+       * pt.c (extract_locals_r): Don't record the local specs of variables
+       declared within the pattern.
+
 2018-04-05  Alexandre Oliva <aoliva@redhat.com>
 
        PR c++/84979
index 741c578b65ba188c1a9b04e8f0231ac33887fe78..ed6e62c2364878d53447f10a8435b735ea72d29a 100644 (file)
@@ -11597,8 +11597,12 @@ tsubst_binary_right_fold (tree t, tree args, tsubst_flags_t complain,
 
 struct el_data
 {
+  hash_set<tree> internal;
   tree extra;
   tsubst_flags_t complain;
+
+  el_data (tsubst_flags_t c)
+    : extra (NULL_TREE), complain (c) {}
 };
 static tree
 extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data_)
@@ -11606,8 +11610,13 @@ extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data_)
   el_data &data = *reinterpret_cast<el_data*>(data_);
   tree *extra = &data.extra;
   tsubst_flags_t complain = data.complain;
-  if (tree spec = retrieve_local_specialization (*tp))
+  if (TREE_CODE (*tp) == DECL_EXPR)
+    data.internal.add (DECL_EXPR_DECL (*tp));
+  else if (tree spec = retrieve_local_specialization (*tp))
     {
+      if (data.internal.contains (*tp))
+       /* Don't mess with variables declared within the pattern.  */
+       return NULL_TREE;
       if (TREE_CODE (spec) == NONTYPE_ARGUMENT_PACK)
        {
          /* Maybe pull out the PARM_DECL for a partial instantiation.  */
@@ -11658,7 +11667,7 @@ extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data_)
 static tree
 extract_local_specs (tree pattern, tsubst_flags_t complain)
 {
-  el_data data = { NULL_TREE, complain };
+  el_data data (complain);
   cp_walk_tree_without_duplicates (&pattern, extract_locals_r, &data);
   return data.extra;
 }
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if19.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if19.C
new file mode 100644 (file)
index 0000000..40016a5
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/85200
+// { dg-additional-options -std=c++17 }
+
+struct A{
+    constexpr operator int(){ return 0; }
+};
+
+template < typename >
+void f(){
+    [](auto known){
+        if constexpr(constexpr int k = known);
+    }(A{});
+}
+
+int main(){
+    f<int>();
+}