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: Fix PR 5333


PR 5333 is an ICE-on-illegal-code.  Here's a fix for the mainline,
tested on i686-pc-linux-gnu, and applied.

On the 3.3 branch, there's no easy fix.  The key problem is that we
are trying to do a variant on the implicit typename extension:
allowing the user to omit both the "typename" and "template" keyword,
in this situation.  In so doing, we lose key information -- and with
the old parser I don't see an easy, safe way around this.

Therefore, I'm going to close the bug, with a note.  Since this is an
ICE-on-illegal, I think that's acceptable.

--
Mark Mitchell                   mark at codesourcery dot com
CodeSourcery, LLC               http://www.codesourcery.com

2003-02-23  Mark Mitchell  <mark at codesourcery dot com>

	PR c++/5333
	* cp-tree.h (CLASSTYPE_PRIMARY_TEMPLATE): New macro.
	* parser.c (cp_parser_diagnose_invalid_type_name): Use it.
	* pt.c (instantiate_class_template): Don't try to instantiate
	dependent types.
	(resolve_typename_type): Use CLASSTYPE_PRIMARY_TEMPLATE.
	
2003-02-23  Mark Mitchell  <mark at codesourcery dot com>

	PR c++/5333
	* g++.dg/parse/fused-params1.C: Adjust error messages.
	* g++.dg/template/nested3.C: New test.
	
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.813
diff -c -5 -p -r1.813 cp-tree.h
*** cp/cp-tree.h	20 Feb 2003 17:51:42 -0000	1.813
--- cp/cp-tree.h	24 Feb 2003 07:39:41 -0000
*************** struct lang_decl GTY(())
*** 2314,2323 ****
--- 2314,2329 ----
  #define ENUM_TI_TEMPLATE(NODE)			\
    TI_TEMPLATE (ENUM_TEMPLATE_INFO (NODE))
  #define ENUM_TI_ARGS(NODE)			\
    TI_ARGS (ENUM_TEMPLATE_INFO (NODE))
  
+ /* For a template instantiation TYPE, returns the TYPE corresponding
+    to the primary template.  */
+ #define CLASSTYPE_PRIMARY_TEMPLATE_TYPE(TYPE)				\
+   TREE_TYPE (DECL_TEMPLATE_RESULT (DECL_PRIMARY_TEMPLATE		\
+ 				   (CLASSTYPE_TI_TEMPLATE ((TYPE)))))
+ 
  /* Like DECL_TI_TEMPLATE, but for an ENUMERAL_, RECORD_, or UNION_TYPE.  */
  #define TYPE_TI_TEMPLATE(NODE)			\
    (TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE)))
  
  /* Like DECL_TI_ARGS, but for an ENUMERAL_, RECORD_, or UNION_TYPE.  */
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.44
diff -c -5 -p -r1.44 parser.c
*** cp/parser.c	20 Feb 2003 17:51:43 -0000	1.44
--- cp/parser.c	24 Feb 2003 07:39:44 -0000
*************** cp_parser_diagnose_invalid_type_name (cp
*** 1952,1965 ****
  		  tree field;
  		  /* Go from a particular instantiation of the
  		     template (which will have an empty TYPE_FIELDs),
  		     to the main version.  */
  		  if (CLASSTYPE_USE_TEMPLATE (base_type))
! 		    base_type = (TREE_TYPE
! 				 (DECL_TEMPLATE_RESULT 
! 				  (DECL_PRIMARY_TEMPLATE
! 				   (CLASSTYPE_TI_TEMPLATE (base_type)))));
  		  for (field = TYPE_FIELDS (base_type);
  		       field;
  		       field = TREE_CHAIN (field))
  		    if (TREE_CODE (field) == TYPE_DECL
  			&& DECL_NAME (field) == name)
--- 1952,1962 ----
  		  tree field;
  		  /* Go from a particular instantiation of the
  		     template (which will have an empty TYPE_FIELDs),
  		     to the main version.  */
  		  if (CLASSTYPE_USE_TEMPLATE (base_type))
! 		    base_type = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (base_type);
  		  for (field = TYPE_FIELDS (base_type);
  		       field;
  		       field = TREE_CHAIN (field))
  		    if (TREE_CODE (field) == TYPE_DECL
  			&& DECL_NAME (field) == name)
*************** cp_parser_unary_operator (cp_token* toke
*** 4524,4533 ****
--- 4521,4531 ----
      }
  }
  
  /* Parse a new-expression.
  
+    new-expression:
       :: [opt] new new-placement [opt] new-type-id new-initializer [opt]
       :: [opt] new new-placement [opt] ( type-id ) new-initializer [opt]
  
     Returns a representation of the expression.  */
  
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.662
diff -c -5 -p -r1.662 pt.c
*** cp/pt.c	20 Feb 2003 17:51:43 -0000	1.662
--- cp/pt.c	24 Feb 2003 07:39:47 -0000
*************** instantiate_class_template (type)
*** 5149,5159 ****
    tree pbinfo;
    
    if (type == error_mark_node)
      return error_mark_node;
  
!   if (TYPE_BEING_DEFINED (type) || COMPLETE_TYPE_P (type))
      return type;
  
    /* Figure out which template is being instantiated.  */
    template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
    my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279);
--- 5149,5161 ----
    tree pbinfo;
    
    if (type == error_mark_node)
      return error_mark_node;
  
!   if (TYPE_BEING_DEFINED (type) 
!       || COMPLETE_TYPE_P (type)
!       || dependent_type_p (type))
      return type;
  
    /* Figure out which template is being instantiated.  */
    template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
    my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279);
*************** resolve_typename_type (tree type, bool o
*** 11524,11533 ****
--- 11526,11539 ----
      return type;
    /* If the SCOPE is not the current instantiation, there's no reason
       to look inside it.  */
    if (only_current_p && !currently_open_class (scope))
      return error_mark_node;
+   /* If SCOPE is a partial instantiation, it will not have a valid
+      TYPE_FIELDS list, so use the original template.  */
+   if (CLASSTYPE_USE_TEMPLATE (scope))
+     scope = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope);
    /* Enter the SCOPE so that name lookup will be resolved as if we
       were in the class definition.  In particular, SCOPE will no
       longer be considered a dependent type.  */
    push_scope (scope);
    /* Look up the declaration.  */
Index: testsuite/g++.dg/parse/fused-params1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/parse/fused-params1.C,v
retrieving revision 1.1
diff -c -5 -p -r1.1 fused-params1.C
*** testsuite/g++.dg/parse/fused-params1.C	6 Feb 2003 22:34:55 -0000	1.1
--- testsuite/g++.dg/parse/fused-params1.C	24 Feb 2003 07:39:49 -0000
***************
*** 1,12 ****
  // PR c++/8785
  // Origin: Alexander Zvyagin <Alexander dot Zviagine at cern dot ch>
  // { dg-do compile }
  
  template <int N,typename T> struct A
! {
      typedef T X;
!     template <int M> void foo (const A<M,X>&); // { dg-error "candidate" }
  };
  
  template <int N,int M,typename T>
  void A<N,T>::foo (const A<M,X>&) {} // { dg-error "" }
--- 1,12 ----
  // PR c++/8785
  // Origin: Alexander Zvyagin <Alexander dot Zviagine at cern dot ch>
  // { dg-do compile }
  
  template <int N,typename T> struct A
! { //  { dg-error "" } 
      typedef T X;
!     template <int M> void foo (const A<M,X>&);
  };
  
  template <int N,int M,typename T>
  void A<N,T>::foo (const A<M,X>&) {} // { dg-error "" }
Index: testsuite/g++.dg/template/nested3.C
===================================================================
RCS file: testsuite/g++.dg/template/nested3.C
diff -N testsuite/g++.dg/template/nested3.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/nested3.C	24 Feb 2003 07:39:49 -0000
***************
*** 0 ****
--- 1,28 ----
+ template <class T1, class T2>
+ class A {
+   template <class S>
+   class SubA {
+     int _k;
+   };
+   T1 _t1;
+   T2 _t2;
+ };
+ 
+ template <class U>
+ class B {
+   class SubB1 {
+     B _i;
+   };
+ 
+   class SubB2 {
+     int _j;
+   };
+   A<U,SubB1>::SubA<SubB2> _a; // { dg-error "" }
+ };
+ 
+ 
+ int main() {
+   B<char> objB;
+ 
+   return 0;
+ }


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