aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2015-06-16 01:59:55 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2015-06-16 01:59:55 +0000
commit04eca83e064da161d8ee91d7ac701625f5f404a2 (patch)
tree732badca01be7ddf1363610c4db6dd06853b9c15
parent4927b383fe3840cf912422b56603711a29e723c1 (diff)
downloadgcc-04eca83e064da161d8ee91d7ac701625f5f404a2.zip
gcc-04eca83e064da161d8ee91d7ac701625f5f404a2.tar.gz
gcc-04eca83e064da161d8ee91d7ac701625f5f404a2.tar.bz2
re PR c++/58583 ([c++11] ICE with invalid non-static data member initialization in template)
cp/ PR c++/58583 * cp-tree.h (DECL_INSTANTIATING_NSDMI_P): New. * init.c (get_nsdmi): Check for DEFAULT_ARG in template case and protect it from recursive instantiation. testsuite/ PR c++/58583 * g++.dg/cpp0x/nsdmi-template14.C: New test. From-SVN: r224502
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/cp-tree.h6
-rw-r--r--gcc/cp/init.c35
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C22
5 files changed, 67 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cf311c7..15766f4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2015-06-15 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/58583
+ * cp-tree.h (DECL_INSTANTIATING_NSDMI_P): New.
+ * init.c (get_nsdmi): Check for DEFAULT_ARG in template case and
+ protect it from recursive instantiation.
+
2015-06-15 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/51048
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1eac636..303a432 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -156,6 +156,7 @@ c-common.h, not after.
2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL).
DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL)
TEMPLATE_DECL_COMPLEX_ALIAS_P (in TEMPLATE_DECL)
+ DECL_INSTANTIATING_NSDMI_P (in a FIELD_DECL)
3: DECL_IN_AGGR_P.
4: DECL_C_BIT_FIELD (in a FIELD_DECL)
DECL_ANON_UNION_VAR_P (in a VAR_DECL)
@@ -3785,6 +3786,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
#define DECL_ARRAY_PARAMETER_P(NODE) \
DECL_LANG_FLAG_1 (PARM_DECL_CHECK (NODE))
+/* Nonzero for a FIELD_DECL who's NSMDI is currently being
+ instantiated. */
+#define DECL_INSTANTIATING_NSDMI_P(NODE) \
+ DECL_LANG_FLAG_2 (FIELD_DECL_CHECK (NODE))
+
/* Nonzero for FIELD_DECL node means that this field is a base class
of the parent object, as opposed to a member field. */
#define DECL_FIELD_IS_BASE(NODE) \
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index ef4f0ff..aa964b9 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -541,6 +541,7 @@ get_nsdmi (tree member, bool in_ctor)
tree init;
tree save_ccp = current_class_ptr;
tree save_ccr = current_class_ref;
+
if (!in_ctor)
{
/* Use a PLACEHOLDER_EXPR when we don't have a 'this' parameter to
@@ -548,22 +549,40 @@ get_nsdmi (tree member, bool in_ctor)
current_class_ref = build0 (PLACEHOLDER_EXPR, DECL_CONTEXT (member));
current_class_ptr = build_address (current_class_ref);
}
+
if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member))
{
- /* Do deferred instantiation of the NSDMI. */
- init = (tsubst_copy_and_build
- (DECL_INITIAL (DECL_TI_TEMPLATE (member)),
- DECL_TI_ARGS (member),
- tf_warning_or_error, member, /*function_p=*/false,
- /*integral_constant_expression_p=*/false));
-
- init = digest_nsdmi_init (member, init);
+ init = DECL_INITIAL (DECL_TI_TEMPLATE (member));
+ if (TREE_CODE (init) == DEFAULT_ARG)
+ goto unparsed;
+
+ /* Check recursive instantiation. */
+ if (DECL_INSTANTIATING_NSDMI_P (member))
+ {
+ error ("recursive instantiation of non-static data member "
+ "initializer for %qD", member);
+ init = error_mark_node;
+ }
+ else
+ {
+ DECL_INSTANTIATING_NSDMI_P (member) = 1;
+
+ /* Do deferred instantiation of the NSDMI. */
+ init = (tsubst_copy_and_build
+ (init, DECL_TI_ARGS (member),
+ tf_warning_or_error, member, /*function_p=*/false,
+ /*integral_constant_expression_p=*/false));
+ init = digest_nsdmi_init (member, init);
+
+ DECL_INSTANTIATING_NSDMI_P (member) = 0;
+ }
}
else
{
init = DECL_INITIAL (member);
if (init && TREE_CODE (init) == DEFAULT_ARG)
{
+ unparsed:
error ("constructor required before non-static data member "
"for %qD has been parsed", member);
DECL_INITIAL (member) = error_mark_node;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 68356fc..57c33d6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-06-15 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/58583
+ * g++.dg/cpp0x/nsdmi-template14.C: New test.
+
2015-06-15 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/51048
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C
new file mode 100644
index 0000000..9cb01f1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C
@@ -0,0 +1,22 @@
+// PR c++/58583
+// { dg-do compile { target c++11 } }
+
+template<int> struct A // { dg-error "has been parsed" }
+{
+ int i = (A<0>(), 0); // { dg-error "has been parsed" }
+};
+
+template<int N> struct B
+{
+ B* p = new B<N>;
+};
+
+B<1> x; // { dg-error "recursive instantiation of non-static data" }
+
+struct C
+{
+ template<int N> struct D
+ {
+ D* p = new D<0>;
+ };
+};