This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 19555
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 30 Jan 2005 22:17:55 -0800
- Subject: C++ PATCH: PR 19555
- Reply-to: mark at codesourcery dot com
This patch fixes an ICE-on-invalid. We were setting
DECL_EXPLICIT_SPECIALIZATION without setting DECL_TEMPLATE_INFO, which
is a very bad idea; the compiler does (and should) assume that
DECL_USE_TEMPLATE -> DECL_TEMPLATE_INFO.
Tested on x86_64-unknown-linux-gnu, applied on the mainline.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
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.
2005-01-30 Mark Mitchell <mark@codesourcery.com>
PR c++/19555
* g++.dg/template/static10.C: New test.
Index: testsuite/g++.dg/template/static10.C
===================================================================
RCS file: testsuite/g++.dg/template/static10.C
diff -N testsuite/g++.dg/template/static10.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/static10.C 31 Jan 2005 06:14:39 -0000
***************
*** 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 "" }
+ }
Index: cp/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/ChangeLog,v
retrieving revision 1.4603
diff -c -5 -p -r1.4603 ChangeLog
*** cp/ChangeLog 31 Jan 2005 04:07:36 -0000 1.4603
--- cp/ChangeLog 31 Jan 2005 06:14:39 -0000
***************
*** 1,7 ****
--- 1,13 ----
2005-01-30 Mark Mitchell <mark@codesourcery.com>
+ PR c++/19555
+ * 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.
PR c++/19367
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1098
diff -c -5 -p -r1.1098 cp-tree.h
*** cp/cp-tree.h 31 Jan 2005 01:16:55 -0000 1.1098
--- cp/cp-tree.h 31 Jan 2005 06:14:39 -0000
*************** struct lang_decl GTY(())
*** 2777,2787 ****
/* Indicates whether or not (and how) a template was expanded for this
FUNCTION_DECL or VAR_DECL.
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); */
#define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.use_template)
#define DECL_TEMPLATE_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) & 1)
#define CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \
(CLASSTYPE_USE_TEMPLATE (NODE) & 1)
--- 2777,2790 ----
/* Indicates whether or not (and how) a template was expanded for this
FUNCTION_DECL or VAR_DECL.
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);
!
! 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)
#define CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \
(CLASSTYPE_USE_TEMPLATE (NODE) & 1)
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1356
diff -c -5 -p -r1.1356 decl.c
*** cp/decl.c 31 Jan 2005 04:07:38 -0000 1.1356
--- cp/decl.c 31 Jan 2005 06:14:39 -0000
*************** duplicate_decls (tree newdecl, tree oldd
*** 1667,1676 ****
--- 1667,1683 ----
DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (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);
DECL_LANG_SPECIFIC (newdecl)->decl_flags.u2 =
DECL_LANG_SPECIFIC (olddecl)->decl_flags.u2;
*************** start_decl (const cp_declarator *declara
*** 3693,3706 ****
decl = field;
}
/* 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))
|| CLASSTYPE_TEMPLATE_INSTANTIATION (context))
{
! 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.
We check for processing_specialization so this only applies
--- 3700,3718 ----
decl = field;
}
/* 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)
|| CLASSTYPE_TEMPLATE_INSTANTIATION (context))
{
! /* 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.
We check for processing_specialization so this only applies