Here the change to look up static/const vars from the enclosing context
of a lambda again at instantiation time was breaking on 4.7 because we
weren't instantiating the lambda op() until EOF. Fixed this way in 4.7;
in later versions we already instantiate it early as part of the
TAG_DEFN. Added the testcase and an assert to the trunk.
Tested x86_64-pc-linux-gnu, applying to trunk and 4.7.
commit f2301b6e7e569c4312c0a3844ac13f76459af597
Author: Jason Merrill <ja...@redhat.com>
Date: Tue May 27 17:12:35 2014 -0400
PR c++/56947
* pt.c (instantiate_decl): Don't defer instantiation of a nested
function.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f2b2f9b..e1cc59d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -18191,6 +18191,7 @@ instantiate_decl (tree d, int defer_ok,
if the variable has a constant value the referring expression can
take advantage of that fact. */
if (TREE_CODE (d) == VAR_DECL
+ || decl_function_context (d)
|| DECL_DECLARED_CONSTEXPR_P (d))
defer_ok = 0;
diff --git a/gcc/testsuite/g++.dg/template/local8.C b/gcc/testsuite/g++.dg/template/local8.C
new file mode 100644
index 0000000..006bd8c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/local8.C
@@ -0,0 +1,18 @@
+// PR c++/56947
+
+struct A
+{
+ A (int);
+};
+
+template < typename >
+void Fn ()
+{
+ const int kCapacity = 0;
+ struct Q:A
+ {
+ Q ():A (kCapacity) { }
+ };
+ Q q;
+}
+template void Fn < int >();
commit 86b12872ec09b670b9be689d5c87c245b1745941
Author: Jason Merrill <ja...@redhat.com>
Date: Thu May 29 17:22:36 2014 -0400
PR c++/56947
* pt.c (instantiate_decl): Check that defer_ok is not set for
local class members.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a24e044..0d22fae 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -19696,6 +19696,11 @@ instantiate_decl (tree d, int defer_ok,
if (external_p && !always_instantiate_p (d))
return d;
+ /* Any local class members should be instantiated from the TAG_DEFN
+ with defer_ok == 0. */
+ gcc_checking_assert (!defer_ok || !decl_function_context (d)
+ || LAMBDA_TYPE_P (DECL_CONTEXT (d)));
+
gen_tmpl = most_general_template (tmpl);
gen_args = DECL_TI_ARGS (d);
diff --git a/gcc/testsuite/g++.dg/template/local8.C b/gcc/testsuite/g++.dg/template/local8.C
new file mode 100644
index 0000000..006bd8c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/local8.C
@@ -0,0 +1,18 @@
+// PR c++/56947
+
+struct A
+{
+ A (int);
+};
+
+template < typename >
+void Fn ()
+{
+ const int kCapacity = 0;
+ struct Q:A
+ {
+ Q ():A (kCapacity) { }
+ };
+ Q q;
+}
+template void Fn < int >();