re PR c++/67041 ([C++14] Variable template initialized by call to lambda does not...
authorJason Merrill <jason@redhat.com>
Tue, 8 Sep 2015 19:33:47 +0000 (15:33 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 8 Sep 2015 19:33:47 +0000 (15:33 -0400)
PR c++/67041
* pt.c (tsubst_copy_and_build): Handle variables like functions.

From-SVN: r227553

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp1y/lambda-var-templ1.C [new file with mode: 0644]

index 6115fd19f0399603c67c9ff0112cb861d3f7d7d1..3a412aeef36e210492796d7c7b08084d4474d312 100644 (file)
@@ -1,3 +1,8 @@
+2015-09-08  Jason Merrill  <jason@redhat.com>
+
+       PR c++/67041
+       * pt.c (tsubst_copy_and_build): Handle variables like functions.
+
 2015-09-08  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/67369
index 2544751cb42c0f757b2d3af1c7454f78de5859c6..05e6d83a3964aff9a0f3cfb82e8c9cce9cf23e99 100644 (file)
@@ -16321,15 +16321,14 @@ tsubst_copy_and_build (tree t,
        LAMBDA_EXPR_MUTABLE_P (r) = LAMBDA_EXPR_MUTABLE_P (t);
        LAMBDA_EXPR_DISCRIMINATOR (r)
          = (LAMBDA_EXPR_DISCRIMINATOR (t));
-       /* For a function scope, we want to use tsubst so that we don't
-          complain about referring to an auto function before its return
-          type has been deduced.  Otherwise, we want to use tsubst_copy so
-          that we look up the existing field/parameter/variable rather
-          than build a new one.  */
        tree scope = LAMBDA_EXPR_EXTRA_SCOPE (t);
-       if (scope && TREE_CODE (scope) == FUNCTION_DECL)
+       if (!scope)
+         /* No substitution needed.  */;
+       else if (VAR_OR_FUNCTION_DECL_P (scope))
+         /* For a function or variable scope, we want to use tsubst so that we
+            don't complain about referring to an auto before deduction.  */
          scope = tsubst (scope, args, complain, in_decl);
-       else if (scope && TREE_CODE (scope) == PARM_DECL)
+       else if (TREE_CODE (scope) == PARM_DECL)
          {
            /* Look up the parameter we want directly, as tsubst_copy
               doesn't do what we need.  */
@@ -16342,8 +16341,12 @@ tsubst_copy_and_build (tree t,
            if (DECL_CONTEXT (scope) == NULL_TREE)
              DECL_CONTEXT (scope) = fn;
          }
-       else
+       else if (TREE_CODE (scope) == FIELD_DECL)
+         /* For a field, use tsubst_copy so that we look up the existing field
+            rather than build a new one.  */
          scope = RECUR (scope);
+       else
+         gcc_unreachable ();
        LAMBDA_EXPR_EXTRA_SCOPE (r) = scope;
        LAMBDA_EXPR_RETURN_TYPE (r)
          = tsubst (LAMBDA_EXPR_RETURN_TYPE (t), args, complain, in_decl);
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-var-templ1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-var-templ1.C
new file mode 100644 (file)
index 0000000..4c2a3cb
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/67041
+// { dg-do compile { target c++14 } }
+
+template<typename T>
+auto test = [](){
+    return T{};
+};
+
+int main() {
+    test<int>();
+}