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 PR8442, 8806, 11513 (some are 3.4 regressions)


Hi

This patch is the updated version of

    http://gcc.gnu.org/ml/gcc-patches/2003-05/msg01475.html

which is a major cleanup and simplification of function 'xref_tag'.
It fixes:
  - PR8442 (a regression in 3.4, already fixed in 3.3)
  - PR8806 (not a regression)
  - PR11513 (a regression in both 3.3 and 3.4, although this patch
             only address 3.4)

The changes from the earlier version of patch are:
  - Use the new DECL_SELF_REFERENCE_P macro instead of DECL_ARTIFICIAL.
  - Adjustment due to earlier janitor patch to unused code removal in
    xref_tag (block inside #ifdef NONNESTED_CLASSES).
  - Add a new testcase for PR11513.

Details of changes is provided in the previous version of the patch
(linked above).

Tested on i686-pc-linux-gnu.  OK for the mainline?

--Kriang



2003-07-19  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/8442, c++/8806, c++/11513
	* decl.c (qualify_lookup): Accept TEMPLATE_DECL if types are
	preferred.
	(check_elaborated_type_specifier): Add allow_template_p
	parameter.  Check tag mismatch and class template.
	(xref_tag): Add template_header_p parameter.  Add assertion
	that name is an IDENTIFIER_NODE.  Remove implicit typename
	warning.  Simplify lookup process if globalize is true.
	(cxx_init_decl_processing): Adjust call to xref_tag.
	* decl2.c (handle_class_head): Likewise.
	* parser.c (cp_parser_elaborated_type_specifier,
	cp_parser_class_head): Likewise.
	* rtti.c (init_rtti_processing, build_dynamic_cast1,
	tinfo_base_init, emit_support_tinfos): Likewise.
	* class.c (is_base_of_enclosing_class): Remove.
	* pt.c (convert_template_argument): Don't accept RECORD_TYPE as
	template template argument.
	* cp-tree.h (xref_tag): Adjust declaration.
	(is_base_of_enclosing_class): Remove.
	* NEWS: Document template template argument change.

2003-07-19  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/8442, c++/8806, c++/11513
	* g++.dg/template/crash8.C: New test.
	* g++.dg/template/elab1.C: Likewise.
	* g++.dg/template/type2.C: Likewise.
	* g++.dg/template/ttp3.C: Adjust expected error message.
	* g++.old-deja/g++.law/visibility13.C: Likewise.
	* g++.old-deja/g++.niklas/t135.C: Likewise.
	* g++.old-deja/g++.pt/ttp41.C: Likewise.
	* g++.old-deja/g++.pt/ttp43.C: Use qualified name for template
	template argument.
	* g++.old-deja/g++.pt/ttp44.C: Likewise.


diff -cprN gcc-main-save/gcc/cp/NEWS gcc-main-new/gcc/cp/NEWS
*** gcc-main-save/gcc/cp/NEWS	Sun Jul 13 22:17:33 2003
--- gcc-main-new/gcc/cp/NEWS	Fri Jul 18 22:51:35 2003
***************
*** 73,78 ****
--- 73,91 ----
  * Covariant returns are implemented for all but varadic functions that
    require an adjustment.
  
+ * Inside the scope of a template class, the name of the class itself
+   is no longer a valid template template argument.  Instead, you now have
+   to qualify the name by its scope.  For example:
+ 
+     template <template <class> class TT> class X {};
+     template <class T> class Y {
+       X<Y> x; // Invalid.
+     };
+ 
+   The valid code for the above example is:
+ 
+       X< ::Y> x; // Valid.  Note that `<:' is a digraph and means `['.
+ 
  *** Changes in GCC 3.3:
  
  * The "new X = 3" extension has been removed; you must now use "new X(3)".
diff -cprN gcc-main-save/gcc/cp/class.c gcc-main-new/gcc/cp/class.c
*** gcc-main-save/gcc/cp/class.c	Thu Jul 17 22:45:22 2003
--- gcc-main-new/gcc/cp/class.c	Fri Jul 18 22:51:36 2003
*************** get_enclosing_class (tree type)
*** 6331,6351 ****
    return NULL_TREE;
  }
  
- /* Return 1 if TYPE or one of its enclosing classes is derived from BASE.  */
- 
- int
- is_base_of_enclosing_class (tree base, tree type)
- {
-   while (type)
-     {
-       if (lookup_base (type, base, ba_any, NULL))
- 	return 1;
- 
-       type = get_enclosing_class (type);
-     }
-   return 0;
- }
- 
  /* Note that NAME was looked up while the current class was being
     defined and that the result of that lookup was DECL.  */
  
--- 6331,6336 ----
diff -cprN gcc-main-save/gcc/cp/cp-tree.h gcc-main-new/gcc/cp/cp-tree.h
*** gcc-main-save/gcc/cp/cp-tree.h	Thu Jul 17 22:45:22 2003
--- gcc-main-new/gcc/cp/cp-tree.h	Fri Jul 18 22:51:36 2003
*************** extern int same_signature_p			(tree, tre
*** 3591,3597 ****
  extern void warn_hidden				(tree);
  extern void maybe_add_class_template_decl_list	(tree, tree, int);
  extern tree get_enclosing_class			(tree);
- int is_base_of_enclosing_class			(tree, tree);
  extern void unreverse_member_declarations       (tree);
  extern void invalidate_class_lookup_cache       (void);
  extern void maybe_note_name_used_in_class       (tree, tree);
--- 3591,3596 ----
*************** extern tree get_scope_of_declarator     
*** 3719,3725 ****
  extern void grok_special_member_properties	(tree);
  extern int grok_ctor_properties			(tree, tree);
  extern void grok_op_properties			(tree, int);
! extern tree xref_tag				(enum tag_types, tree, tree, bool);
  extern tree xref_tag_from_type			(tree, tree, int);
  extern void xref_basetypes			(tree, tree);
  extern tree start_enum				(tree);
--- 3718,3724 ----
  extern void grok_special_member_properties	(tree);
  extern int grok_ctor_properties			(tree, tree);
  extern void grok_op_properties			(tree, int);
! extern tree xref_tag				(enum tag_types, tree, tree, bool, bool);
  extern tree xref_tag_from_type			(tree, tree, int);
  extern void xref_basetypes			(tree, tree);
  extern tree start_enum				(tree);
diff -cprN gcc-main-save/gcc/cp/decl.c gcc-main-new/gcc/cp/decl.c
*** gcc-main-save/gcc/cp/decl.c	Thu Jul 17 22:45:22 2003
--- gcc-main-new/gcc/cp/decl.c	Fri Jul 18 23:16:20 2003
*************** qualify_lookup (tree val, int flags)
*** 5751,5757 ****
      return val;
    if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
      return val;
!   if ((flags & LOOKUP_PREFER_TYPES) && TREE_CODE (val) == TYPE_DECL)
      return val;
    if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
      return NULL_TREE;
--- 5751,5758 ----
      return val;
    if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
      return val;
!   if ((flags & LOOKUP_PREFER_TYPES)
!       && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL))
      return val;
    if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
      return NULL_TREE;
*************** cxx_init_decl_processing (void)
*** 6343,6349 ****
      push_namespace (std_identifier);
      bad_alloc_type_node 
        = xref_tag (class_type, get_identifier ("bad_alloc"), 
! 		  /*attributes=*/NULL_TREE, 1);
      pop_namespace ();
      ptr_ftype_sizetype 
        = build_function_type (ptr_type_node,
--- 6344,6350 ----
      push_namespace (std_identifier);
      bad_alloc_type_node 
        = xref_tag (class_type, get_identifier ("bad_alloc"), 
! 		  /*attributes=*/NULL_TREE, true, false);
      pop_namespace ();
      ptr_ftype_sizetype 
        = build_function_type (ptr_type_node,
*************** tag_name (enum tag_types code)
*** 12557,12567 ****
  /* Name lookup in an elaborated-type-specifier (after the keyword
     indicated by TAG_CODE) has found TYPE.  If the
     elaborated-type-specifier is invalid, issue a diagnostic and return
!    error_mark_node; otherwise, return TYPE itself.  */
  
  static tree
  check_elaborated_type_specifier (enum tag_types tag_code,
! 				 tree type)
  {
    tree t;
  
--- 12558,12570 ----
  /* Name lookup in an elaborated-type-specifier (after the keyword
     indicated by TAG_CODE) has found TYPE.  If the
     elaborated-type-specifier is invalid, issue a diagnostic and return
!    error_mark_node; otherwise, return TYPE itself.  
!    If ALLOW_TEMPLATE_P is true, TYPE may be a class template.  */
  
  static tree
  check_elaborated_type_specifier (enum tag_types tag_code,
! 				 tree type,
! 				 bool allow_template_p)
  {
    tree t;
  
*************** check_elaborated_type_specifier (enum ta
*** 12582,12611 ****
  	     type, tag_name (tag_code));
        t = error_mark_node;
      }
  
    return t;
  }
  
! /* Get the struct, enum or union (CODE says which) with tag NAME.
     Define the tag as a forward-reference if it is not defined.
  
!    C++: If a class derivation is given, process it here, and report
!    an error if multiple derivation declarations are not identical.
  
!    If this is a definition, come in through xref_tag and only look in
     the current frame for the name (since C++ allows new names in any
!    scope.)  */
  
  tree
  xref_tag (enum tag_types tag_code, tree name, tree attributes, 
! 	  bool globalize)
  {
    enum tree_code code;
!   register tree ref, t;
    struct cp_binding_level *b = current_binding_level;
    tree context = NULL_TREE;
  
    timevar_push (TV_NAME_LOOKUP);
    switch (tag_code)
      {
      case record_type:
--- 12585,12650 ----
  	     type, tag_name (tag_code));
        t = error_mark_node;
      }
+   else if (TREE_CODE (type) == ENUMERAL_TYPE
+ 	   && tag_code != enum_type)
+     {
+       error ("`%T' referred to as `%s'", type, tag_name (tag_code));
+       t = error_mark_node;
+     }
+   else if (TREE_CODE (type) != ENUMERAL_TYPE
+ 	   && tag_code == enum_type)
+     {
+       error ("`%T' referred to as enum", type);
+       t = error_mark_node;
+     }
+   else if (!allow_template_p
+ 	   && TREE_CODE (type) == RECORD_TYPE
+ 	   && CLASSTYPE_IS_TEMPLATE (type))
+     {
+       /* If a class template appears as elaborate type specifier
+ 	 without a template header such as:
+ 
+ 	   template <class T> class C {};
+ 	   void f(class C);		// No template header here
+ 
+ 	 then the required template argument is missing.  */
+ 
+       error ("template argument required for `%s %T'",
+ 	     tag_name (tag_code),
+ 	     DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)));
+       t = error_mark_node;
+     }
  
    return t;
  }
  
! /* Get the struct, enum or union (TAG_CODE says which) with tag NAME.
     Define the tag as a forward-reference if it is not defined.
  
!    If a declaration is given, process it here, and report an error if
!    multiple declarations are not identical.  ATTRIBUTE is the attribute
!    appeared in this declaration.
  
!    GLOBALIZE is false when this is also a definition.  Only look in
     the current frame for the name (since C++ allows new names in any
!    scope.)
! 
!    TEMPLATE_HEADER_P is true when this declaration is preceded by
!    a set of template parameters.  */
  
  tree
  xref_tag (enum tag_types tag_code, tree name, tree attributes, 
! 	  bool globalize, bool template_header_p)
  {
    enum tree_code code;
!   register tree t;
    struct cp_binding_level *b = current_binding_level;
    tree context = NULL_TREE;
  
    timevar_push (TV_NAME_LOOKUP);
+ 
+   my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0);
+ 
    switch (tag_code)
      {
      case record_type:
*************** xref_tag (enum tag_types tag_code, tree 
*** 12622,12714 ****
        abort ();
      }
  
-   /* If a cross reference is requested, look up the type
-      already defined for this tag and return it.  */
-   if (TYPE_P (name))
-     {
-       t = name;
-       name = TYPE_IDENTIFIER (t);
-     }
-   else
-     t = IDENTIFIER_TYPE_VALUE (name);
- 
-   /* Warn about 'friend struct Inherited;' doing the wrong thing.  */
-   if (t && globalize && TREE_CODE (t) == TYPENAME_TYPE)
-     {
-       static int explained;
-       tree shadowed;
- 
-       warning ("`%s %T' declares a new type at namespace scope",
- 		  tag_name (tag_code), name);
-       if (!explained++)
- 	warning ("  names from dependent base classes are not visible to unqualified name lookup - to refer to the inherited type, say `%s %T::%T'",
- 		    tag_name (tag_code),
- 		    constructor_name (current_class_type),
- 		    TYPE_IDENTIFIER (t));
- 
-       /* We need to remove the class scope binding for the
-          TYPENAME_TYPE as otherwise poplevel_class gets confused.  */
-       for (shadowed = b->class_shadowed;
- 	   shadowed;
- 	   shadowed = TREE_CHAIN (shadowed))
- 	if (TREE_TYPE (shadowed) == TYPE_NAME (t))
- 	  {
- 	    TREE_PURPOSE (shadowed) = NULL_TREE;
- 	    break;
- 	  }
-     }
- 
-   if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM
-       && TREE_CODE (t) != BOUND_TEMPLATE_TEMPLATE_PARM)
-     t = NULL_TREE;
- 
    if (! globalize)
      {
        /* If we know we are defining this tag, only look it up in
  	 this scope and don't try to find it as a type.  */
!       ref = lookup_tag (code, name, b, 1);
      }
    else
      {
!       if (t)
! 	{
! 	  ref = check_elaborated_type_specifier (tag_code, t);
! 	  if (ref == error_mark_node)
  	    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
  	}
        else
! 	ref = lookup_tag (code, name, b, 0);
  
!       if (! ref)
! 	{
! 	  /* Try finding it as a type declaration.  If that wins,
! 	     use it.  */
! 	  ref = lookup_name (name, 1);
! 
! 	  if (ref != NULL_TREE
! 	      && processing_template_decl
! 	      && DECL_CLASS_TEMPLATE_P (ref)
! 	      && template_class_depth (current_class_type) == 0)
! 	    /* Since GLOBALIZE is true, we're declaring a global
! 	       template, so we want this type.  */
! 	    ref = DECL_TEMPLATE_RESULT (ref);
! 
! 	  if (ref && TREE_CODE (ref) == TYPE_DECL)
! 	    {
! 	      ref = check_elaborated_type_specifier (tag_code, 
! 						     TREE_TYPE (ref));
! 	      if (ref == error_mark_node)
! 		POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
! 	      if (ref && TREE_CODE (ref) != code)
! 		ref = NULL_TREE;
! 	    }
! 	  else
! 	    ref = NULL_TREE;
! 	}
! 
!       if (ref && current_class_type
  	  && template_class_depth (current_class_type)
! 	  && PROCESSING_REAL_TEMPLATE_DECL_P ())
  	{
  	  /* Since GLOBALIZE is nonzero, we are not looking at a
  	     definition of this tag.  Since, in addition, we are currently
--- 12661,12714 ----
        abort ();
      }
  
    if (! globalize)
      {
        /* If we know we are defining this tag, only look it up in
  	 this scope and don't try to find it as a type.  */
!       t = lookup_tag (code, name, b, 1);
      }
    else
      {
!       tree decl = lookup_name (name, 1);
! 
!       /* True if DECL is a self reference created inside a class.  */
!       bool implicit_typedef_p = (decl && TREE_CODE (decl) == TYPE_DECL
! 				 && DECL_SELF_REFERENCE_P (decl));
! 
!       if (decl && DECL_CLASS_TEMPLATE_P (decl))
! 	decl = DECL_TEMPLATE_RESULT (decl);
! 
!       if (decl && TREE_CODE (decl) == TYPE_DECL)
! 	{
! 	  /* Two cases needed to be consider when deciding if a
! 	     class template is allowed as an elaborated type specifier:
! 	     1. It's an implicit typedef.
! 	     2. It comes with a template header.
! 
! 	     For example:
! 
! 	       template <class T> class C {
! 		 class C *c1;		// implicit_typedef_p is true
! 	 	 class D;
! 	       };
! 	       template <class U> class C; // template_header_p is true
! 	       template <class T> class C<T>::D {
! 		 class C *c2;		// implicit_typedef_p is true
! 	       };  */
! 
! 	  t = check_elaborated_type_specifier (tag_code, 
! 					       TREE_TYPE (decl),
! 					       template_header_p
! 					       | implicit_typedef_p);
! 	  if (t == error_mark_node)
  	    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
  	}
        else
! 	t = NULL_TREE;
  
!       if (t && current_class_type
  	  && template_class_depth (current_class_type)
! 	  && template_header_p)
  	{
  	  /* Since GLOBALIZE is nonzero, we are not looking at a
  	     definition of this tag.  Since, in addition, we are currently
*************** xref_tag (enum tag_types tag_code, tree 
*** 12746,12757 ****
  	      accomplish this by making sure that the new type we
  	      create to represent this declaration has the right
  	      TYPE_CONTEXT.  */
! 	  context = TYPE_CONTEXT (ref);
! 	  ref = NULL_TREE;
  	}
      }
  
!   if (! ref)
      {
        /* If no such tag is yet defined, create a forward-reference node
  	 and record it as the "definition".
--- 12746,12757 ----
  	      accomplish this by making sure that the new type we
  	      create to represent this declaration has the right
  	      TYPE_CONTEXT.  */
! 	  context = TYPE_CONTEXT (t);
! 	  t = NULL_TREE;
  	}
      }
  
!   if (! t)
      {
        /* If no such tag is yet defined, create a forward-reference node
  	 and record it as the "definition".
*************** xref_tag (enum tag_types tag_code, tree 
*** 12761,12804 ****
  	{
  	  error ("use of enum `%#D' without previous declaration", name);
  
! 	  ref = make_node (ENUMERAL_TYPE);
  
  	  /* Give the type a default layout like unsigned int
  	     to avoid crashing if it does not get defined.  */
! 	  TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
! 	  TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node);
! 	  TYPE_USER_ALIGN (ref) = 0;
! 	  TREE_UNSIGNED (ref) = 1;
! 	  TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node);
! 	  TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node);
! 	  TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node);
  
  	  /* Enable us to recognize when a type is created in class context.
  	     To do nested classes correctly, this should probably be cleared
  	     out when we leave this classes scope.  Currently this in only
  	     done in `start_enum'.  */
  
! 	  pushtag (name, ref, globalize);
  	}
        else
  	{
! 	  struct cp_binding_level *old_b = class_binding_level;
! 
! 	  ref = make_aggr_type (code);
! 	  TYPE_CONTEXT (ref) = context;
! 	  pushtag (name, ref, globalize);
! 	  class_binding_level = old_b;
  	}
      }
    else
      {
!       if (!globalize && processing_template_decl && IS_AGGR_TYPE (ref))
! 	redeclare_class_template (ref, current_template_parms);
      }
  
!   TYPE_ATTRIBUTES (ref) = attributes;
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ref);
  }
  
  tree
--- 12761,12801 ----
  	{
  	  error ("use of enum `%#D' without previous declaration", name);
  
! 	  t = make_node (ENUMERAL_TYPE);
  
  	  /* Give the type a default layout like unsigned int
  	     to avoid crashing if it does not get defined.  */
! 	  TYPE_MODE (t) = TYPE_MODE (unsigned_type_node);
! 	  TYPE_ALIGN (t) = TYPE_ALIGN (unsigned_type_node);
! 	  TYPE_USER_ALIGN (t) = 0;
! 	  TREE_UNSIGNED (t) = 1;
! 	  TYPE_PRECISION (t) = TYPE_PRECISION (unsigned_type_node);
! 	  TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (unsigned_type_node);
! 	  TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (unsigned_type_node);
  
  	  /* Enable us to recognize when a type is created in class context.
  	     To do nested classes correctly, this should probably be cleared
  	     out when we leave this classes scope.  Currently this in only
  	     done in `start_enum'.  */
  
! 	  pushtag (name, t, globalize);
  	}
        else
  	{
! 	  t = make_aggr_type (code);
! 	  TYPE_CONTEXT (t) = context;
! 	  pushtag (name, t, globalize);
  	}
      }
    else
      {
!       if (!globalize && processing_template_decl && IS_AGGR_TYPE (t))
! 	redeclare_class_template (t, current_template_parms);
      }
  
!   TYPE_ATTRIBUTES (t) = attributes;
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
  }
  
  tree
*************** xref_tag_from_type (tree old, tree id, i
*** 12814,12820 ****
    if (id == NULL_TREE)
      id = TYPE_IDENTIFIER (old);
  
!   return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize);
  }
  
  /* REF is a type (named NAME), for which we have just seen some
--- 12811,12817 ----
    if (id == NULL_TREE)
      id = TYPE_IDENTIFIER (old);
  
!   return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize, false);
  }
  
  /* REF is a type (named NAME), for which we have just seen some
diff -cprN gcc-main-save/gcc/cp/decl2.c gcc-main-new/gcc/cp/decl2.c
*** gcc-main-save/gcc/cp/decl2.c	Thu Jul 10 19:51:26 2003
--- gcc-main-new/gcc/cp/decl2.c	Fri Jul 18 22:51:36 2003
*************** handle_class_head (enum tag_types tag_ki
*** 4307,4313 ****
    
    if (!decl)
      {
!       decl = xref_tag (tag_kind, id, attributes, false);
        if (decl == error_mark_node)
  	return error_mark_node;
        decl = TYPE_MAIN_DECL (decl);
--- 4307,4313 ----
    
    if (!decl)
      {
!       decl = xref_tag (tag_kind, id, attributes, false, false);
        if (decl == error_mark_node)
  	return error_mark_node;
        decl = TYPE_MAIN_DECL (decl);
diff -cprN gcc-main-save/gcc/cp/parser.c gcc-main-new/gcc/cp/parser.c
*** gcc-main-save/gcc/cp/parser.c	Thu Jul 17 22:45:22 2003
--- gcc-main-new/gcc/cp/parser.c	Fri Jul 18 22:51:36 2003
*************** cp_parser_elaborated_type_specifier (cp_
*** 8562,8568 ****
  			   (is_friend 
  			    || !is_declaration
  			    || cp_lexer_next_token_is_not (parser->lexer, 
! 							   CPP_SEMICOLON)));
  	}
      }
    if (tag_type != enum_type)
--- 8562,8569 ----
  			   (is_friend 
  			    || !is_declaration
  			    || cp_lexer_next_token_is_not (parser->lexer, 
! 							   CPP_SEMICOLON)),
! 			   parser->num_template_parameter_lists);
  	}
      }
    if (tag_type != enum_type)
*************** cp_parser_class_head (cp_parser* parser,
*** 11389,11395 ****
        /* If the class was unnamed, create a dummy name.  */
        if (!id)
  	id = make_anon_name ();
!       type = xref_tag (class_key, id, attributes, /*globalize=*/0);
      }
    else
      {
--- 11390,11397 ----
        /* If the class was unnamed, create a dummy name.  */
        if (!id)
  	id = make_anon_name ();
!       type = xref_tag (class_key, id, attributes, /*globalize=*/false,
! 		       parser->num_template_parameter_lists);
      }
    else
      {
diff -cprN gcc-main-save/gcc/cp/pt.c gcc-main-new/gcc/cp/pt.c
*** gcc-main-save/gcc/cp/pt.c	Fri Jul 18 21:00:55 2003
--- gcc-main-new/gcc/cp/pt.c	Fri Jul 18 22:51:36 2003
*************** convert_template_argument (tree parm, 
*** 3438,3470 ****
    requires_type = (TREE_CODE (parm) == TYPE_DECL
  		   || requires_tmpl_type);
  
!   if (TREE_CODE (arg) != RECORD_TYPE)
!     is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL
! 		     && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
! 		    || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
! 		    || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
!   else if (CLASSTYPE_TEMPLATE_INFO (arg) && !CLASSTYPE_USE_TEMPLATE (arg)
! 	   && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (arg)))
!     {
!       if (is_base_of_enclosing_class (arg, current_class_type))
! 	/* This is a template name used within the scope of the
! 	   template. It could be the template, or it could be the
! 	   instantiation. Choose whichever makes sense.  */
! 	is_tmpl_type = requires_tmpl_type;
!       else
! 	is_tmpl_type = 1;
!     }
!   else
!     /* It is a non-template class, or a specialization of a template
!        class, or a non-template member of a template class.  */
!     is_tmpl_type = 0;
    
    if (is_tmpl_type
        && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
  	  || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE))
      arg = TYPE_STUB_DECL (arg);
-   else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE)
-     arg = CLASSTYPE_TI_TEMPLATE (arg);
  
    is_type = TYPE_P (arg) || is_tmpl_type;
  
--- 3438,3452 ----
    requires_type = (TREE_CODE (parm) == TYPE_DECL
  		   || requires_tmpl_type);
  
!   is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL
! 		   && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
! 		  || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
! 		  || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
    
    if (is_tmpl_type
        && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
  	  || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE))
      arg = TYPE_STUB_DECL (arg);
  
    is_type = TYPE_P (arg) || is_tmpl_type;
  
diff -cprN gcc-main-save/gcc/cp/rtti.c gcc-main-new/gcc/cp/rtti.c
*** gcc-main-save/gcc/cp/rtti.c	Tue Jul  8 22:34:49 2003
--- gcc-main-new/gcc/cp/rtti.c	Fri Jul 18 22:51:36 2003
*************** init_rtti_processing (void)
*** 119,125 ****
    push_namespace (std_identifier);
    type_info_type_node 
      = xref_tag (class_type, get_identifier ("type_info"),
! 		/*attributes=*/NULL_TREE, 1);
    pop_namespace ();
    const_type_info_type = build_qualified_type (type_info_type_node, 
  					       TYPE_QUAL_CONST);
--- 119,125 ----
    push_namespace (std_identifier);
    type_info_type_node 
      = xref_tag (class_type, get_identifier ("type_info"),
! 		/*attributes=*/NULL_TREE, true, false);
    pop_namespace ();
    const_type_info_type = build_qualified_type (type_info_type_node, 
  					       TYPE_QUAL_CONST);
*************** build_dynamic_cast_1 (tree type, tree ex
*** 640,646 ****
  	      tinfo_ptr = xref_tag (class_type,
  				    get_identifier ("__class_type_info"),
  				    /*attributes=*/NULL_TREE,
! 				    1);
  	      
  	      tinfo_ptr = build_pointer_type
  		(build_qualified_type
--- 640,646 ----
  	      tinfo_ptr = xref_tag (class_type,
  				    get_identifier ("__class_type_info"),
  				    /*attributes=*/NULL_TREE,
! 				    true, false);
  	      
  	      tinfo_ptr = build_pointer_type
  		(build_qualified_type
*************** tinfo_base_init (tree desc, tree target)
*** 777,783 ****
    
        push_nested_namespace (abi_node);
        real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
! 			    /*attributes=*/NULL_TREE, 1);
        pop_nested_namespace (abi_node);
    
        if (!COMPLETE_TYPE_P (real_type))
--- 777,783 ----
    
        push_nested_namespace (abi_node);
        real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
! 			    /*attributes=*/NULL_TREE, true, false);
        pop_nested_namespace (abi_node);
    
        if (!COMPLETE_TYPE_P (real_type))
*************** emit_support_tinfos (void)
*** 1374,1380 ****
    bltn_type = xref_tag (class_type,
  			get_identifier ("__fundamental_type_info"), 
  			/*attributes=*/NULL_TREE,
! 			1);
    pop_nested_namespace (abi_node);
    if (!COMPLETE_TYPE_P (bltn_type))
      return;
--- 1374,1380 ----
    bltn_type = xref_tag (class_type,
  			get_identifier ("__fundamental_type_info"), 
  			/*attributes=*/NULL_TREE,
! 			true, false);
    pop_nested_namespace (abi_node);
    if (!COMPLETE_TYPE_P (bltn_type))
      return;
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/crash8.C gcc-main-new/gcc/testsuite/g++.dg/template/crash8.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/crash8.C	Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/crash8.C	Sat Jul 19 19:54:18 2003
***************
*** 0 ****
--- 1,20 ----
+ // { dg-do compile }
+ 
+ // Origin: David Robinson <drtr@dial.pipex.com>
+ 
+ // PR c++/11513: ICE due to incorrect decision whether the tag is template.
+ 
+ template <typename T>
+ struct bar
+ { 
+   struct foo
+   {
+     int a;
+   };
+ 
+   template <typename U>
+   int wom(U c)
+   {
+     struct foo b;
+   }
+ };
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/elab1.C gcc-main-new/gcc/testsuite/g++.dg/template/elab1.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/elab1.C	Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/elab1.C	Fri Jul 18 22:51:36 2003
***************
*** 0 ****
--- 1,13 ----
+ // Copyright (C) 2003 Free Software Foundation
+ // Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ // { dg-do compile }
+ 
+ // Elaborate type specifier of class template
+ 
+ template <class T> class A {
+   class B;
+ };
+ 
+ template <class T> class A<T>::B {
+   friend class A;
+ };
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/ttp3.C gcc-main-new/gcc/testsuite/g++.dg/template/ttp3.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/ttp3.C	Mon Jan 27 16:59:56 2003
--- gcc-main-new/gcc/testsuite/g++.dg/template/ttp3.C	Fri Jul 18 22:51:36 2003
*************** class OUTER {
*** 14,26 ****
    template <class T>
    class List { };
    
!   vector<class List> data; // { dg-error "type/value mismatch|expected a type|ISO C" "" }
  };
  
  template <class T>
! class List { };			// { dg-bogus "previous declaration" "" { xfail *-*-* } }
  
  // This next line should just do a lookup of 'class List', and then
  // get a type/value mismatch. Instead we try and push 'class List'
  // into the global namespace and get a redeclaration error.
! vector<class List > data;	// { dg-bogus "`struct List' redeclared|type/value mismatch" "" { xfail *-*-* } }
--- 14,26 ----
    template <class T>
    class List { };
    
!   vector<class List> data; // { dg-error "invalid|required|ISO C" "" }
  };
  
  template <class T>
! class List { };
  
  // This next line should just do a lookup of 'class List', and then
  // get a type/value mismatch. Instead we try and push 'class List'
  // into the global namespace and get a redeclaration error.
! vector<class List > data;	// { dg-error "invalid|required|expected" "" }
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/type2.C gcc-main-new/gcc/testsuite/g++.dg/template/type2.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/type2.C	Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/type2.C	Fri Jul 18 22:51:36 2003
***************
*** 0 ****
--- 1,16 ----
+ // { dg-do compile }
+ // Origin: Juan Carlos Arevalo-Baeza <jcab@JCABs-Rumblings.com>
+ 
+ // PR c++/8442
+ // Type template parameter incorrectly treated as template template
+ // parameter.
+ 
+ template <typename T> struct A {};
+ 
+ template <typename T> struct B
+ {
+   template <typename U> struct C {};
+   template <typename U> A<C<U> > foo(U);
+ };
+ 
+ B<void> b;
diff -cprN gcc-main-save/gcc/testsuite/g++.old-deja/g++.law/visibility13.C gcc-main-new/gcc/testsuite/g++.old-deja/g++.law/visibility13.C
*** gcc-main-save/gcc/testsuite/g++.old-deja/g++.law/visibility13.C	Thu May  1 18:35:03 2003
--- gcc-main-new/gcc/testsuite/g++.old-deja/g++.law/visibility13.C	Fri Jul 18 22:51:36 2003
*************** void Array<Type>::init(const Type *array
*** 65,71 ****
  //     ---------------   Array_RC.h  &&  Array_RC.cc   ----------------
  
  template <class Type>
! class Array_RC : public Array<Type> {// { dg-error "" } previous declaration.*
  public:
      Array_RC(const Type *ar, int sz);
      Type& operator[](int ix);
--- 65,71 ----
  //     ---------------   Array_RC.h  &&  Array_RC.cc   ----------------
  
  template <class Type>
! class Array_RC : public Array<Type> {
  public:
      Array_RC(const Type *ar, int sz);
      Type& operator[](int ix);
diff -cprN gcc-main-save/gcc/testsuite/g++.old-deja/g++.niklas/t135.C gcc-main-new/gcc/testsuite/g++.old-deja/g++.niklas/t135.C
*** gcc-main-save/gcc/testsuite/g++.old-deja/g++.niklas/t135.C	Thu May  1 18:35:10 2003
--- gcc-main-new/gcc/testsuite/g++.old-deja/g++.niklas/t135.C	Fri Jul 18 22:51:36 2003
***************
*** 1,7 ****
! // { dg-do assemble }
  // GROUPS niklas pt friend
  template <class T> class C1
! { // { dg-error "" }
  public:
  	void diddle_C2 ();
  };
--- 1,7 ----
! // { dg-do compile }
  // GROUPS niklas pt friend
  template <class T> class C1
! {
  public:
  	void diddle_C2 ();
  };
diff -cprN gcc-main-save/gcc/testsuite/g++.old-deja/g++.pt/ttp41.C gcc-main-new/gcc/testsuite/g++.old-deja/g++.pt/ttp41.C
*** gcc-main-save/gcc/testsuite/g++.old-deja/g++.pt/ttp41.C	Thu May  1 18:35:31 2003
--- gcc-main-new/gcc/testsuite/g++.old-deja/g++.pt/ttp41.C	Fri Jul 18 22:51:36 2003
***************
*** 1,4 ****
! // { dg-do run  }
  template<template<class> class D,class E> class C
  {
  	public:
--- 1,4 ----
! // { dg-do compile }
  template<template<class> class D,class E> class C
  {
  	public:
*************** template<class T> class D
*** 13,20 ****
  
  template<class T> int D<T>::f()
  {
! 	C<D,D> c;
! 	return c.g();
  }
  
  int main()
--- 13,20 ----
  
  template<class T> int D<T>::f()
  {
! 	C<D,D> c;	// { dg-error "" }
! 	return c.g();	// { dg-error "" }
  }
  
  int main()
diff -cprN gcc-main-save/gcc/testsuite/g++.old-deja/g++.pt/ttp43.C gcc-main-new/gcc/testsuite/g++.old-deja/g++.pt/ttp43.C
*** gcc-main-save/gcc/testsuite/g++.old-deja/g++.pt/ttp43.C	Thu May  1 18:35:31 2003
--- gcc-main-new/gcc/testsuite/g++.old-deja/g++.pt/ttp43.C	Fri Jul 18 22:51:36 2003
*************** struct Lit {
*** 20,30 ****
  
  template < class T >
  struct Id {
!   Add < T, Id, Lit > operator+(const T& t) const {
!     return Add < T, Id, Lit >(*this, Lit<T>(t));
    }
  
!   Mul < T, Id, Lit > operator*(const T& t) const {
!     return Mul < T, Id, Lit >(*this, Lit<T>(t));
    }
  };
--- 20,30 ----
  
  template < class T >
  struct Id {
!   Add < T, ::Id, Lit > operator+(const T& t) const {
!     return Add < T, ::Id, Lit >(*this, Lit<T>(t));
    }
  
!   Mul < T, ::Id, Lit > operator*(const T& t) const {
!     return Mul < T, ::Id, Lit >(*this, Lit<T>(t));
    }
  };
diff -cprN gcc-main-save/gcc/testsuite/g++.old-deja/g++.pt/ttp44.C gcc-main-new/gcc/testsuite/g++.old-deja/g++.pt/ttp44.C
*** gcc-main-save/gcc/testsuite/g++.old-deja/g++.pt/ttp44.C	Thu May  1 18:35:31 2003
--- gcc-main-new/gcc/testsuite/g++.old-deja/g++.pt/ttp44.C	Fri Jul 18 22:51:36 2003
*************** public:
*** 9,16 ****
  template < class T >
  struct Id {
    template < template < class > class E >
!   Add < T, Id, E > operator+(const E<T>& e) const {
!     return Add < T, Id, E >(*this, e);
    }
  };
  
--- 9,16 ----
  template < class T >
  struct Id {
    template < template < class > class E >
!   Add < T, ::Id, E > operator+(const E<T>& e) const {
!     return Add < T, ::Id, E >(*this, e);
    }
  };
  


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