This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/85200, ICE with constexpr if in generic lambda


Since, during partial instantiation of a generic lambda, we don't
substitute into the body of a constexpr if, we don't do lambda capture
as part of substitution.  But extract_locals_r is supposed to do it as
part of remembering the substitution context to be used later.

As it turns out, this was failing because walk_tree_1 expects the
DECL_INITIAL of a local variable to be walked in the context of the
BIND_EXPR, but we don't build BIND_EXPRs for compound-statements in a
template.  So in a template, let's walk the fields of a VAR_DECL from
its DECL_EXPR.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit a99a47e6326b7278d660dcebba8ebcbec863f04a
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Apr 4 14:24:34 2018 -0400

            PR c++/85200 - ICE with constexpr if in generic lambda.
    
            * tree.c (cp_walk_subtrees): Walk into DECL_EXPR in templates.

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 7ddc2cb5e2d..d0835cfaa29 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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
index 00000000000..03ad620e8d9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if18.C
@@ -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>();
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]