From 2b1e8a76efd4aa5d8a9aa111016fe26eca7e6308 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 31 Jan 2005 06:16:54 +0000 Subject: [PATCH] re PR c++/19555 (specialized in the wrong namespace causes an ICE) PR c++/19555 * cp-tree.h (DECL_USE_TEMPLATE): Expand documentation. * decl.c (duplicate_decls): Do not discard DECL_IMPLICIT_INSTANTIATION when merging declarations. (start_decl): Do not SET_DECL_TEMPLATE_SPECIALIZATION for variables that do not have DECL_USE_TEMPLATE. PR c++/19555 * g++.dg/template/static10.C: New test. From-SVN: r94469 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/cp-tree.h | 5 ++++- gcc/cp/decl.c | 16 ++++++++++++++-- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/template/static10.C | 23 +++++++++++++++++++++++ 5 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/static10.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0b1f7d1a3de..e205886c863 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2005-01-30 Mark Mitchell + PR c++/19555 + * cp-tree.h (DECL_USE_TEMPLATE): Expand documentation. + * decl.c (duplicate_decls): Do not discard + DECL_IMPLICIT_INSTANTIATION when merging declarations. + (start_decl): Do not SET_DECL_TEMPLATE_SPECIALIZATION for + variables that do not have DECL_USE_TEMPLATE. + PR c++/19395 * decl.c (grokdeclarator): Refactor code so that qualified names are never allowed as the declarator in a typedef. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ced845b8428..cb0c25b3694 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2779,7 +2779,10 @@ struct lang_decl GTY(()) 0=normal declaration, e.g. int min (int, int); 1=implicit template instantiation 2=explicit template specialization, e.g. int min (int, int); - 3=explicit template instantiation, e.g. template int min (int, int); */ + 3=explicit template instantiation, e.g. template int min (int, int); + + If DECL_USE_TEMPLATE is non-zero, then DECL_TEMPLATE_INFO will also + be non-NULL. */ #define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.use_template) #define DECL_TEMPLATE_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) & 1) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e2408e36b82..e72b183c6b6 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1669,6 +1669,13 @@ duplicate_decls (tree newdecl, tree olddecl) DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl); DECL_TEMPLATE_INSTANTIATED (newdecl) |= DECL_TEMPLATE_INSTANTIATED (olddecl); + /* If the OLDDECL is an implicit instantiation, then the NEWDECL + must be too. But, it may not yet be marked as such if the + caller has created NEWDECL, but has not yet figured out that + it is a redeclaration. */ + if (DECL_IMPLICIT_INSTANTIATION (olddecl) + && !DECL_USE_TEMPLATE (newdecl)) + SET_DECL_IMPLICIT_INSTANTIATION (newdecl); /* Don't really know how much of the language-specific values we should copy from old to new. */ DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl); @@ -3695,10 +3702,15 @@ start_decl (const cp_declarator *declarator, /* cp_finish_decl sets DECL_EXTERNAL if DECL_IN_AGGR_P is set. */ DECL_IN_AGGR_P (decl) = 0; - if ((DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl)) + if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl) || CLASSTYPE_TEMPLATE_INSTANTIATION (context)) { - SET_DECL_TEMPLATE_SPECIALIZATION (decl); + /* Do not mark DECL as an explicit specialization if it was + not already marked as an instantiation; a declaration + should never be marked as a specialization unless we know + what template is being specialized. */ + if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl)) + SET_DECL_TEMPLATE_SPECIALIZATION (decl); /* [temp.expl.spec] An explicit specialization of a static data member of a template is a definition if the declaration includes an initializer; otherwise, it is a declaration. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0d7f5306e9d..30a3bca86f1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2005-01-30 Mark Mitchell + PR c++/19555 + * g++.dg/template/static10.C: New test. + PR c++/19395 * g++.dg/parse/error24.C: New test. diff --git a/gcc/testsuite/g++.dg/template/static10.C b/gcc/testsuite/g++.dg/template/static10.C new file mode 100644 index 00000000000..ab857bd814e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static10.C @@ -0,0 +1,23 @@ +// PR c++/19555 + +namespace __gnu_debug_def { } +namespace std +{ + using namespace __gnu_debug_def; + template class allocator {}; +} +namespace __gnu_debug_def +{ + template > + class vector + { + void + swap(vector<_Tp,_Allocator>& __x); + }; +} +namespace std +{ + template<> void + vector >::swap(vector >&) { } // { dg-error "" } +} -- 2.30.2