From 59bfec983fd2836c58b2093bb3f576801744807e Mon Sep 17 00:00:00 2001 From: mmitchel Date: Wed, 19 Jul 2006 00:22:43 +0000 Subject: [PATCH] PR c++/28235 * pt.c (tsubst_decl): Handling substitutions into a static data member from within the scope of the tempalte itself. PR c++/28235 * g++.dg/template/static27.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@115576 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 +++ gcc/cp/pt.c | 70 +++++++++++++++++++++----------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/template/static27.C | 13 ++++++ 4 files changed, 71 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/static27.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cf7a062bd61..2f22450fb82 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2006-07-18 Mark Mitchell + + PR c++/28235 + * pt.c (tsubst_decl): Handling substitutions into a static data + member from within the scope of the tempalte itself. + 2006-07-18 Lee Millward PR c++/28258 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 873ef51990e..7c099644d35 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6673,7 +6673,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) tree tmpl = NULL_TREE; tree ctx; tree type = NULL_TREE; - int local_p; + bool local_p; if (TREE_CODE (t) == TYPE_DECL) { @@ -6691,40 +6691,64 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) } } - /* Assume this is a non-local variable. */ - local_p = 0; + /* Check to see if we already have the specialization we + need. */ + spec = NULL_TREE; + if (DECL_CLASS_SCOPE_P (t) || DECL_NAMESPACE_SCOPE_P (t)) + { + /* T is a static data member or namespace-scope entity. + We have to substitute into namespace-scope variables + (even though such entities are never templates) because + of cases like: + + template void f() { extern T t; } + + where the entity referenced is not known until + instantiation time. */ + local_p = false; + ctx = DECL_CONTEXT (t); + if (DECL_CLASS_SCOPE_P (t)) + { + ctx = tsubst_aggr_type (ctx, args, + complain, + in_decl, /*entering_scope=*/1); + /* If CTX is unchanged, then T is in fact the + specialization we want. That situation occurs when + referencing a static data member within in its own + class. We can use pointer equality, rather than + same_type_p, because DECL_CONTEXT is always + canonical. */ + if (ctx == DECL_CONTEXT (t)) + spec = t; + } - if (TYPE_P (CP_DECL_CONTEXT (t))) - ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, - complain, - in_decl, /*entering_scope=*/1); - else if (DECL_NAMESPACE_SCOPE_P (t)) - ctx = DECL_CONTEXT (t); + if (!spec) + { + tmpl = DECL_TI_TEMPLATE (t); + gen_tmpl = most_general_template (tmpl); + argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl); + spec = (retrieve_specialization + (gen_tmpl, argvec, + /*class_specializations_p=*/false)); + } + } else { + /* A local variable. */ + local_p = true; /* Subsequent calls to pushdecl will fill this in. */ ctx = NULL_TREE; - local_p = 1; + spec = retrieve_local_specialization (t); } - - /* Check to see if we already have this specialization. */ - if (!local_p) - { - tmpl = DECL_TI_TEMPLATE (t); - gen_tmpl = most_general_template (tmpl); - argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl); - spec = retrieve_specialization (gen_tmpl, argvec, - /*class_specializations_p=*/false); - } - else - spec = retrieve_local_specialization (t); - + /* If we already have the specialization we need, there is + nothing more to do. */ if (spec) { r = spec; break; } + /* Create a new node for the specialization we need. */ r = copy_decl (t); if (TREE_CODE (r) == VAR_DECL) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 505a2adcaf4..604b6cdb06d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-07-18 Mark Mitchell + + PR c++/28235 + * g++.dg/template/static27.C: New test. + 2006-07-18 Diego Novillo PR 28410 diff --git a/gcc/testsuite/g++.dg/template/static27.C b/gcc/testsuite/g++.dg/template/static27.C new file mode 100644 index 00000000000..0b63967e352 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static27.C @@ -0,0 +1,13 @@ +// PR c++/28235 + +template struct A +{ + static const bool i = true; + template struct B {}; + B<> b; +}; + +void f() { + A a1, a2; + a1.b = a2.b; +} -- 2.11.0