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 22147


This patch fixes an ICE-on-valid regression in 4.1.

We have a forward declaration of a class in a template-argument list
for a friend function; in that case the new class is not a template.

Tested on x86_64-unknown-linux-gnu, applied on the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2005-09-27  Mark Mitchell  <mark@codesourcery.com>

	PR c++/22147
	* name-lookup.c (maybe_process_template_type_declaration): Don't
	treat forward declarations of classes as templates just because
	we're processing_template_decl.
	* pt.c (tsubst_decl): Clear DECL_TEMPLATE_INFO for friend
	functions. 

2005-09-27  Mark Mitchell  <mark@codesourcery.com>

	PR c++/22147
	* g++.dg/template/friend37.C: New test.
	* g++.dg/parse/crash28.C: Adjust error markers.
	
Index: gcc/cp/name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.141
diff -c -5 -p -r1.141 name-lookup.c
*** gcc/cp/name-lookup.c	12 Sep 2005 19:54:01 -0000	1.141
--- gcc/cp/name-lookup.c	27 Sep 2005 23:25:49 -0000
*************** maybe_process_template_type_declaration 
*** 4686,4695 ****
--- 4686,4700 ----
  
  	 template <class A*> struct S;
  
         is a forward-declaration of `A'.  */
      ;
+   else if (b->kind == sk_namespace
+ 	   && current_binding_level->kind != sk_namespace)
+     /* If this new type is being injected into a containing scope,
+        then it's not a template type.  */
+     ;
    else
      {
        gcc_assert (IS_AGGR_TYPE (type) || TREE_CODE (type) == ENUMERAL_TYPE);
  
        if (processing_template_decl)
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.1038
diff -c -5 -p -r1.1038 pt.c
*** gcc/cp/pt.c	16 Sep 2005 15:41:38 -0000	1.1038
--- gcc/cp/pt.c	27 Sep 2005 23:25:50 -0000
*************** tsubst_decl (tree t, tree args, tsubst_f
*** 6508,6517 ****
--- 6508,6519 ----
  	    if (!member
  		&& !PRIMARY_TEMPLATE_P (gen_tmpl)
  		&& !uses_template_parms (argvec))
  	      tsubst_default_arguments (r);
  	  }
+ 	else
+ 	  DECL_TEMPLATE_INFO (r) = NULL_TREE;
  
  	/* Copy the list of befriending classes.  */
  	for (friends = &DECL_BEFRIENDING_CLASSES (r);
  	     *friends;
  	     friends = &TREE_CHAIN (*friends))
Index: gcc/testsuite/g++.dg/parse/crash28.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/parse/crash28.C,v
retrieving revision 1.1
diff -c -5 -p -r1.1 crash28.C
*** gcc/testsuite/g++.dg/parse/crash28.C	11 Aug 2005 09:23:57 -0000	1.1
--- gcc/testsuite/g++.dg/parse/crash28.C	27 Sep 2005 23:25:52 -0000
***************
*** 4,14 ****
  // PR 23219, ICE
  // Origin:Andrew Pinski <pinskia@gcc.gnu.org>
  //        Volker Reichelt <reichelt@gcc.gnu.org>
  
  template <class _Tp> class insert_iterator<slist<_Tp> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" }
! template <class _Value> class insert_iterator<int > { // { dg-error "template parameters not used|_Value" }
    hash_set<_Value>; // { dg-error "no type|expected" }
  };
  
  template<int> struct A<X<> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" }
! struct A {}; // { dg-error "template argument required" }
--- 4,14 ----
  // PR 23219, ICE
  // Origin:Andrew Pinski <pinskia@gcc.gnu.org>
  //        Volker Reichelt <reichelt@gcc.gnu.org>
  
  template <class _Tp> class insert_iterator<slist<_Tp> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" }
! template <class _Value> class insert_iterator<int > { // { dg-error "template" }
    hash_set<_Value>; // { dg-error "no type|expected" }
  };
  
  template<int> struct A<X<> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" }
! struct A {};
Index: gcc/testsuite/g++.dg/template/friend37.C
===================================================================
RCS file: gcc/testsuite/g++.dg/template/friend37.C
diff -N gcc/testsuite/g++.dg/template/friend37.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/template/friend37.C	27 Sep 2005 23:25:52 -0000
***************
*** 0 ****
--- 1,15 ----
+ // PR c++/22147
+ 
+ template<typename> struct A;
+ 
+ template<typename T> void foo(A<T>* p) { *p; }
+ 
+ template<typename> struct A
+ {
+   friend void foo<class X>(A<X>*);
+ };
+ 
+ void bar()
+ {
+   foo<int>(0);
+ }


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