summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2005-01-31 06:16:54 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2005-01-31 06:16:54 +0000
commit55e5ccb918aaad56d1650af5a968448f09124b95 (patch)
treef7c2fcad7da81ca7390ed264d37a6079512631d9 /gcc
parentef0fa62495ec60b517f8baaeeba85ca73347f5e8 (diff)
downloadgcc-55e5ccb918aaad56d1650af5a968448f09124b95.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94469 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/cp-tree.h5
-rw-r--r--gcc/cp/decl.c16
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/template/static10.C23
5 files changed, 51 insertions, 3 deletions
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 <mark@codesourcery.com>
+ 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, int);
- 3=explicit template instantiation, e.g. template int min<int> (int, int); */
+ 3=explicit template instantiation, e.g. template int min<int> (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 <mark@codesourcery.com>
+ 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<typename _Tp> class allocator {};
+}
+namespace __gnu_debug_def
+{
+ template<typename _Tp,
+ typename _Allocator = std::allocator<_Tp> >
+ class vector
+ {
+ void
+ swap(vector<_Tp,_Allocator>& __x);
+ };
+}
+namespace std
+{
+ template<> void
+ vector<int, allocator<int> >::swap(vector<int, allocator<int> >&) { } // { dg-error "" }
+}