From cb3037199c8e3ca9f7982ec3a0024f8ab007cfbb Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 9 Sep 2014 07:59:45 -0400 Subject: [PATCH] re PR c++/62255 (Introducing an unrelated template parameter causes compilation to fail) PR c++/62255 * pt.c (instantiate_decl): Handle recursive instantiation of static data member. From-SVN: r215062 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/pt.c | 19 ++++++++++++------- gcc/testsuite/g++.dg/template/recurse4.C | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/recurse4.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3d872313930..6447bc71795 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2014-09-08 Jason Merrill + + PR c++/62255 + * pt.c (instantiate_decl): Handle recursive instantiation of + static data member. + 2014-09-05 Jason Merrill PR c++/62659 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5ea5a5854d8..38093ecd67d 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -19996,13 +19996,18 @@ instantiate_decl (tree d, int defer_ok, args, tf_warning_or_error, NULL_TREE, /*integral_constant_expression_p=*/false); - /* Make sure the initializer is still constant, in case of - circular dependency (template/instantiate6.C). */ - const_init - = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (code_pattern); - cp_finish_decl (d, init, /*init_const_expr_p=*/const_init, - /*asmspec_tree=*/NULL_TREE, - LOOKUP_ONLYCONVERTING); + /* If instantiating the initializer involved instantiating this + again, don't call cp_finish_decl twice. */ + if (!DECL_INITIAL (d)) + { + /* Make sure the initializer is still constant, in case of + circular dependency (template/instantiate6.C). */ + const_init + = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (code_pattern); + cp_finish_decl (d, init, /*init_const_expr_p=*/const_init, + /*asmspec_tree=*/NULL_TREE, + LOOKUP_ONLYCONVERTING); + } if (enter_context) pop_nested_class (); pop_nested_namespace (ns); diff --git a/gcc/testsuite/g++.dg/template/recurse4.C b/gcc/testsuite/g++.dg/template/recurse4.C new file mode 100644 index 00000000000..ee8d1b70df9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/recurse4.C @@ -0,0 +1,18 @@ +// PR c++/62255 + +// It's not clear whether this is well-formed; instantiating the +// initializer of 'value' causes the instantiation of Derived, which in +// turn requires the value of 'value', but the recursion ends there, so it +// seems reasonable to allow it. + +template struct Test { + template static int check(typename X::Type*); + template static char check(...); + static const bool value = (sizeof(check(0)) == sizeof(int)); +}; +template struct Sink { }; +template struct Derived : Sink >::value> { + typedef int Type; +}; + +Sink >::value> s;