From 2d22db1f2a4c0e98dc3be3bbe2512252d530b599 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Sun, 16 Oct 2005 23:17:53 +0000 Subject: [PATCH] re PR c++/24389 (template variable not getting marked as weak) PR c++/24389 * decl2.c (mark_used): Use uses_template_parms instead of dependent_type_p. * init.c (constant_value_1): Handle uninstantiated templates specially. * pt.c (instantiate_decl): Add sanity check. PR c++/24389 * g++.dg/template/static21.C: New test. * g++.dg/template/static21-a.cc: Likewise. From-SVN: r105474 --- gcc/cp/ChangeLog | 9 ++++++ gcc/cp/decl2.c | 34 ++++++++++++--------- gcc/cp/init.c | 31 +++++++++++++------ gcc/cp/pt.c | 4 +++ gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/g++.dg/template/static21-a.cc | 17 +++++++++++ gcc/testsuite/g++.dg/template/static21.C | 20 ++++++++++++ 7 files changed, 96 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/static21-a.cc create mode 100644 gcc/testsuite/g++.dg/template/static21.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2896ce26dc7..9305e162458 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2005-10-16 Mark Mitchell + + PR c++/24389 + * decl2.c (mark_used): Use uses_template_parms instead of + dependent_type_p. + * init.c (constant_value_1): Handle uninstantiated templates + specially. + * pt.c (instantiate_decl): Add sanity check. + 2005-10-16 Mark Mitchell PR c++/22173 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 1e812838435..70ca017d9e4 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3253,22 +3253,26 @@ mark_used (tree decl) DECL. However, if DECL is a static data member initialized with a constant, we need the value right now because a reference to such a data member is not value-dependent. */ - if (processing_template_decl) - { - if (TREE_CODE (decl) == VAR_DECL - && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) - && DECL_CLASS_SCOPE_P (decl) - && !dependent_type_p (DECL_CONTEXT (decl))) - { - /* Pretend that we are not in a template so that the - initializer for the static data member will be full - simplified. */ - saved_processing_template_decl = processing_template_decl; - processing_template_decl = 0; - } - else - return; + if (TREE_CODE (decl) == VAR_DECL + && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) + && DECL_CLASS_SCOPE_P (decl)) + { + /* Don't try to instantiate members of dependent types. We + cannot just use dependent_type_p here because this function + may be called from fold_non_dependent_expr, and then we may + see dependent types, even though processing_template_decl + will not be set. */ + if (CLASSTYPE_TEMPLATE_INFO ((DECL_CONTEXT (decl))) + && uses_template_parms (CLASSTYPE_TI_ARGS (DECL_CONTEXT (decl)))) + return; + /* Pretend that we are not in a template, even if we are, so + that the static data member initializer will be processed. */ + saved_processing_template_decl = processing_template_decl; + processing_template_decl = 0; } + + if (processing_template_decl) + return; if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl) && !TREE_ASM_WRITTEN (decl)) diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 809b74fa98a..44cfc440628 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1576,16 +1576,27 @@ constant_value_1 (tree decl, bool integral_p) && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl))))) { tree init; - /* If DECL is a static data member in a template class, we must - instantiate it here. The initializer for the static data - member is not processed until needed; we need it now. */ - mark_used (decl); - init = DECL_INITIAL (decl); - /* If we are currently processing a template, the - initializer for a static data member may not be dependent, - but it is not folded until instantiation time. */ - if (init) - init = fold_non_dependent_expr (init); + /* Static data members in template classes may have + non-dependent initializers. References to such non-static + data members are no value-dependent, so we must retrieve the + initializer here. The DECL_INITIAL will have the right type, + but will not have been folded because that would prevent us + from performing all appropriate semantic checks at + instantiation time. */ + if (DECL_CLASS_SCOPE_P (decl) + && CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl)) + && uses_template_parms (CLASSTYPE_TI_ARGS + (DECL_CONTEXT (decl)))) + init = fold_non_dependent_expr (DECL_INITIAL (decl)); + else + { + /* If DECL is a static data member in a template + specialization, we must instantiate it here. The + initializer for the static data member is not processed + until needed; we need it now. */ + mark_used (decl); + init = DECL_INITIAL (decl); + } if (!(init || init == error_mark_node) || !TREE_TYPE (init) || (integral_p diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 1ef5669a82d..3de54a4e377 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11502,6 +11502,10 @@ instantiate_decl (tree d, int defer_ok, td = template_for_substitution (d); code_pattern = DECL_TEMPLATE_RESULT (td); + /* We should never be trying to instantiate a member of a class + template or partial specialization. */ + gcc_assert (d != code_pattern); + if ((DECL_NAMESPACE_SCOPE_P (d) && !DECL_INITIALIZED_IN_CLASS_P (d)) || DECL_TEMPLATE_SPECIALIZATION (td)) /* In the case of a friend template whose definition is provided diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 034df789092..373a7977a25 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-10-16 Mark Mitchell + + PR c++/24389 + * g++.dg/template/static21.C: New test. + * g++.dg/template/static21-a.cc: Likewise. + 2005-10-16 Andrew Pinski PR c++/23959 diff --git a/gcc/testsuite/g++.dg/template/static21-a.cc b/gcc/testsuite/g++.dg/template/static21-a.cc new file mode 100644 index 00000000000..9489ae7d0b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static21-a.cc @@ -0,0 +1,17 @@ +template + struct X + { + static const int n_primes = 256; + static const unsigned long primes[n_primes + 1]; + }; + + template + const int X::n_primes; + + template + const unsigned long X::primes[n_primes + 1] = + { 0 }; + + +const unsigned long *f1(void){return &X<0>::primes[0];} +int main(){} diff --git a/gcc/testsuite/g++.dg/template/static21.C b/gcc/testsuite/g++.dg/template/static21.C new file mode 100644 index 00000000000..66b045087fa --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static21.C @@ -0,0 +1,20 @@ +// PR c++/24389 +// { dg-additional-sources "static21-a.cc" } +// { dg-do link } + +template +struct X +{ + static const int n_primes = 256; + static const unsigned long primes[n_primes + 1]; +}; + +template +const int X::n_primes; + +template +const unsigned long X::primes[n_primes + 1] = + { 0 }; + +const unsigned long *f(void){return &X<0>::primes[0];} + -- 2.30.2