aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2005-10-16 23:17:53 +0000
committerMark Mitchell <mark@codesourcery.com>2005-10-16 23:17:53 +0000
commit883647e4e34ec7a1996f3dc86e772d0367a55bfa (patch)
tree3618dcffe2507c601f8aff3bb13ef29ad2ae0551
parent2aa50476dd0270be2c0dfd98efcb3314f83abcca (diff)
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: https://gcc.gnu.org/svn/gcc/trunk@105474 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/decl2.c34
-rw-r--r--gcc/cp/init.c31
-rw-r--r--gcc/cp/pt.c4
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/template/static21-a.cc17
-rw-r--r--gcc/testsuite/g++.dg/template/static21.C20
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];}
+