diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-10-16 23:17:53 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-10-16 23:17:53 +0000 |
commit | 5c028b29a218419112e82694df26e9f434d2344e (patch) | |
tree | 3618dcffe2507c601f8aff3bb13ef29ad2ae0551 | |
parent | 25c41c32d7afed5c728fed06f34bb0b26a3f4f9a (diff) | |
download | gcc-5c028b29a218419112e82694df26e9f434d2344e.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@105474 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 34 | ||||
-rw-r--r-- | gcc/cp/init.c | 31 | ||||
-rw-r--r-- | gcc/cp/pt.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/static21-a.cc | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/static21.C | 20 |
7 files changed, 96 insertions, 25 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2896ce26dc7..9305e162458 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,14 @@ 2005-10-16 Mark Mitchell <mark@codesourcery.com> + 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 <mark@codesourcery.com> + PR c++/22173 * typeck.c (check_template_keyword): Fix thinko. 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 <mark@codesourcery.com> + + PR c++/24389 + * g++.dg/template/static21.C: New test. + * g++.dg/template/static21-a.cc: Likewise. + 2005-10-16 Andrew Pinski <pinskia@physics.uc.edu> 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<int dummy> + struct X + { + static const int n_primes = 256; + static const unsigned long primes[n_primes + 1]; + }; + + template<int dummy> + const int X<dummy>::n_primes; + + template<int dummy> + const unsigned long X<dummy>::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<int dummy> +struct X +{ + static const int n_primes = 256; + static const unsigned long primes[n_primes + 1]; +}; + +template<int dummy> +const int X<dummy>::n_primes; + +template<int dummy> +const unsigned long X<dummy>::primes[n_primes + 1] = + { 0 }; + +const unsigned long *f(void){return &X<0>::primes[0];} + |