PR c++/85200 - ICE with constexpr if in generic lambda.
authorJason Merrill <jason@redhat.com>
Wed, 4 Apr 2018 19:10:38 +0000 (15:10 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 4 Apr 2018 19:10:38 +0000 (15:10 -0400)
* tree.c (cp_walk_subtrees): Walk into DECL_EXPR in templates.

From-SVN: r259099

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

index 9b754199e696beff7283fbd528b071a554cb5620..12d0c10efd5072ddc0c28db0b3b7f26658a96458 100644 (file)
@@ -1,5 +1,8 @@
 2018-04-04  Jason Merrill  <jason@redhat.com>
 
+       PR c++/85200 - ICE with constexpr if in generic lambda.
+       * tree.c (cp_walk_subtrees): Walk into DECL_EXPR in templates.
+
        PR c++/84221 - bogus -Wunused with attribute and template.
        * decl2.c (is_late_template_attribute): Handle unused and used
        normally on non-TYPE_DECL.
index 7ddc2cb5e2df48b3000a9d60f6b8f540ff80b907..d0835cfaa2901f0ffb64f41b9754e6564faeac64 100644 (file)
@@ -4894,10 +4894,12 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
       /* User variables should be mentioned in BIND_EXPR_VARS
         and their initializers and sizes walked when walking
         the containing BIND_EXPR.  Compiler temporaries are
-        handled here.  */
+        handled here.  And also normal variables in templates,
+        since do_poplevel doesn't build a BIND_EXPR then.  */
       if (VAR_P (TREE_OPERAND (*tp, 0))
-         && DECL_ARTIFICIAL (TREE_OPERAND (*tp, 0))
-         && !TREE_STATIC (TREE_OPERAND (*tp, 0)))
+         && (processing_template_decl
+             || (DECL_ARTIFICIAL (TREE_OPERAND (*tp, 0))
+                 && !TREE_STATIC (TREE_OPERAND (*tp, 0)))))
        {
          tree decl = TREE_OPERAND (*tp, 0);
          WALK_SUBTREE (DECL_INITIAL (decl));
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if18.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if18.C
new file mode 100644 (file)
index 0000000..03ad620
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/85200
+// { dg-additional-options -std=c++17 }
+
+template <typename T>
+void f(){
+  [](auto v, auto b){
+    if constexpr (sizeof(v) == sizeof(int)) {
+       auto x = b;
+      }
+  }(0, 1);
+}
+
+int main(){
+  f<int>();
+}