PR c++/79640 - infinite recursion with generic lambda.
authorJason Merrill <jason@redhat.com>
Mon, 20 Mar 2017 18:49:10 +0000 (14:49 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 20 Mar 2017 18:49:10 +0000 (14:49 -0400)
* pt.c (tsubst_copy) [VAR_DECL]: Register the dummy instantiation
before substituting its initializer.

From-SVN: r246289

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

index a356fc779242ee1dd6333bb4d69ed05461394f75..2797f8c71574df382b3b77a905ebe3bedda927e8 100644 (file)
@@ -1,3 +1,9 @@
+2017-03-20  Jason Merrill  <jason@redhat.com>
+
+       PR c++/79640 - infinite recursion with generic lambda.
+       * pt.c (tsubst_copy) [VAR_DECL]: Register the dummy instantiation
+       before substituting its initializer.
+
 2017-03-20  Marek Polacek  <polacek@redhat.com>
            Paolo Carlini  <paolo.carlini@oracle.com>
 
index b8ce9fedf429f25ecc3d97fc6b59c5604b8495d2..f18071068154a8af5f311782a8a4edfd26e1fa0c 100644 (file)
@@ -14581,6 +14581,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                     local static or constant.  Building a new VAR_DECL
                     should be OK in all those cases.  */
                  r = tsubst_decl (t, args, complain);
+                 if (local_specializations)
+                   /* Avoid infinite recursion (79640).  */
+                   register_local_specialization (r, t);
                  if (decl_maybe_constant_var_p (r))
                    {
                      /* We can't call cp_finish_decl, so handle the
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const3.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const3.C
new file mode 100644 (file)
index 0000000..9c9dbac
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/79640
+// { dg-do compile { target c++14 } }
+
+template<typename F> void foo(F f)
+{
+  f(1);
+}
+
+template<int> void bar()
+{
+  const int i = i;
+  foo([] (auto) { sizeof(i); });
+}
+
+void baz() { bar<1>(); }