This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: PR 19555


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]