aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-10-13 17:23:47 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-10-13 17:23:47 -0400
commit2598165f09a96f60aa53abebf931718a769b7cf2 (patch)
tree6bfe09b345ceaed634c1718cf2d97aba8fa3b824
parent0e81aa85294d479dea3fb9b5a71e6f7242770af6 (diff)
downloadgcc-2598165f09a96f60aa53abebf931718a769b7cf2.zip
gcc-2598165f09a96f60aa53abebf931718a769b7cf2.tar.gz
gcc-2598165f09a96f60aa53abebf931718a769b7cf2.tar.bz2
re PR c++/50614 ([C++0x] ICE: tree check: expected field_decl, have identifier_node in component_ref_field_offset, at expr.c:6697 with -fcompare-debug and a non-static initializer)
PR c++/50614 * cp-tree.h (VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK): New. (DECL_TEMPLATE_INFO): Use it. * pt.c (tsubst_decl) [FIELD_DECL]: Set DECL_TEMPLATE_INFO if the decl has an NSDMI. * init.c (perform_member_init): Use it. From-SVN: r179945
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/cp-tree.h10
-rw-r--r--gcc/cp/init.c6
-rw-r--r--gcc/cp/pt.c10
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-template2.C14
6 files changed, 45 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0322103..9a214b5 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,12 @@
2011-10-13 Jason Merrill <jason@redhat.com>
+ PR c++/50614
+ * cp-tree.h (VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK): New.
+ (DECL_TEMPLATE_INFO): Use it.
+ * pt.c (tsubst_decl) [FIELD_DECL]: Set DECL_TEMPLATE_INFO
+ if the decl has an NSDMI.
+ * init.c (perform_member_init): Use it.
+
PR c++/50437
* cp-tree.h (struct tree_lambda_expr): Add closure field.
(LAMBDA_EXPR_CLOSURE): New.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index bae6071..88f7fbd 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -201,6 +201,9 @@ c-common.h, not after.
#define VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK(NODE) \
TREE_CHECK4(NODE,VAR_DECL,FUNCTION_DECL,TYPE_DECL,TEMPLATE_DECL)
+#define VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK(NODE) \
+ TREE_CHECK5(NODE,VAR_DECL,FIELD_DECL,FUNCTION_DECL,TYPE_DECL,TEMPLATE_DECL)
+
#define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE) \
TREE_CHECK(NODE,BOUND_TEMPLATE_TEMPLATE_PARM)
@@ -2556,7 +2559,7 @@ extern void decl_shadowed_for_var_insert (tree, tree);
global function f. In this case, DECL_TEMPLATE_INFO for S<int>::f
will be non-NULL, but DECL_USE_TEMPLATE will be zero. */
#define DECL_TEMPLATE_INFO(NODE) \
- (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \
+ (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK (NODE)) \
->u.min.template_info)
/* For a VAR_DECL, indicates that the variable is actually a
@@ -2701,7 +2704,10 @@ extern void decl_shadowed_for_var_insert (tree, tree);
template <class T> struct S { friend void f<int>(int, double); }
the DECL_TI_TEMPLATE will be an IDENTIFIER_NODE for `f' and the
- DECL_TI_ARGS will be {int}. */
+ DECL_TI_ARGS will be {int}.
+
+ For a FIELD_DECL with a non-static data member initializer, this value
+ is the FIELD_DECL it was instantiated from. */
#define DECL_TI_TEMPLATE(NODE) TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE))
/* The template arguments used to obtain this decl from the most
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index a21e566..4561979 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -497,11 +497,11 @@ perform_member_init (tree member, tree init)
mem-initializer for this field. */
if (init == NULL_TREE)
{
- if (CLASSTYPE_TEMPLATE_INSTANTIATION (DECL_CONTEXT (member)))
+ if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member))
/* Do deferred instantiation of the NSDMI. */
init = (tsubst_copy_and_build
- (DECL_INITIAL (member),
- CLASSTYPE_TI_ARGS (DECL_CONTEXT (member)),
+ (DECL_INITIAL (DECL_TI_TEMPLATE (member)),
+ DECL_TI_ARGS (member),
tf_warning_or_error, member, /*function_p=*/false,
/*integral_constant_expression_p=*/false));
else
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 880f3d1..1632c01 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10269,6 +10269,16 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
= tsubst_expr (DECL_INITIAL (t), args,
complain, in_decl,
/*integral_constant_expression_p=*/true);
+ else if (DECL_INITIAL (t))
+ {
+ /* Set up DECL_TEMPLATE_INFO so that we can get at the
+ NSDMI in perform_member_init. Still set DECL_INITIAL
+ to error_mark_node so that we know there is one. */
+ DECL_INITIAL (r) = error_mark_node;
+ gcc_assert (DECL_LANG_SPECIFIC (r) == NULL);
+ retrofit_lang_decl (r);
+ DECL_TEMPLATE_INFO (r) = build_template_info (t, args);
+ }
/* We don't have to set DECL_CONTEXT here; it is set by
finish_member_declaration. */
DECL_CHAIN (r) = NULL_TREE;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3c15036..9c29b70 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2011-10-13 Jason Merrill <jason@redhat.com>
+ PR c++/50614
+ * g++.dg/cpp0x/nsdmi-template2.C: New.
+
PR c++/50437
* g++.dg/cpp0x/lambda/lambda-auto1.C: New.
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template2.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template2.C
new file mode 100644
index 0000000..27b0aa5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template2.C
@@ -0,0 +1,14 @@
+// PR c++/50614
+// { dg-options "-std=c++0x -fcompare-debug" }
+
+struct A
+{
+ int f ();
+};
+
+template <int> struct B : A
+{
+ int i = this->f ();
+};
+
+B<0> b;