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 for 4.0] Fix PR18652 (ICE redeclaring variable as classtemplate)


Hi

This patch fixes a regression in 4.0 that produces ICE on invalid
code:
	int A;
	template<int> struct A;

The function 'duplicate_decls' detects the conflict in the above code
and returns error_mark_node. However, push_template_decl_real fails to check this error_mark_node.


Further more, there is no way that the current pushtag can tell the caller whether the operation succeed so that the caller can continue using the RECORD_TYPE/ENUMERAL_TYPE node or discard it. This is fixed
by changing the return type of pushtag from 'void' to 'tree'.


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

--Kriang


2004-11-14  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/18652
	* name-lookup.c (pushtag): Change return type to tree.
	* cp-tree.h (pushtag): Adjust declaration.
	* decl.c (xref_tag, start_enum): Use return value of pushtag.
	* pt.c (push_template_decl_real): Return immediately if
	pushdecl_namespace_level returns error_mark_node.

2004-11-14  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/18652
	* g++.dg/lookup/crash6.C: New test.


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	Sat Nov 27 00:05:57 2004
--- gcc-main-new/gcc/cp/cp-tree.h	Sat Nov 27 17:56:31 2004
*************** extern void delete_block			(tree);
*** 3707,3713 ****
  extern void add_block_current_level		(tree);
  extern void push_switch				(tree);
  extern void pop_switch				(void);
! extern void pushtag				(tree, tree, int);
  extern tree make_anon_name			(void);
  extern int decls_match				(tree, tree);
  extern tree duplicate_decls			(tree, tree);
--- 3707,3713 ----
  extern void add_block_current_level		(tree);
  extern void push_switch				(tree);
  extern void pop_switch				(void);
! extern tree pushtag				(tree, tree, int);
  extern tree make_anon_name			(void);
  extern int decls_match				(tree, tree);
  extern tree duplicate_decls			(tree, tree);
diff -cprN gcc-main-save/gcc/cp/decl.c gcc-main-new/gcc/cp/decl.c
*** gcc-main-save/gcc/cp/decl.c	Sat Nov 27 00:05:57 2004
--- gcc-main-new/gcc/cp/decl.c	Sat Nov 27 17:56:19 2004
*************** xref_tag (enum tag_types tag_code, tree 
*** 9284,9290 ****
  	  t = make_aggr_type (code);
  	  TYPE_CONTEXT (t) = context;
  	  /* pushtag only cares whether SCOPE is zero or not.  */
! 	  pushtag (name, t, scope != ts_current);
  	}
      }
    else
--- 9284,9290 ----
  	  t = make_aggr_type (code);
  	  TYPE_CONTEXT (t) = context;
  	  /* pushtag only cares whether SCOPE is zero or not.  */
! 	  t = pushtag (name, t, scope != ts_current);
  	}
      }
    else
*************** start_enum (tree name)
*** 9539,9545 ****
  	name = make_anon_name ();
  
        enumtype = make_node (ENUMERAL_TYPE);
!       pushtag (name, enumtype, 0);
      }
  
    return enumtype;
--- 9539,9545 ----
  	name = make_anon_name ();
  
        enumtype = make_node (ENUMERAL_TYPE);
!       enumtype = pushtag (name, enumtype, 0);
      }
  
    return enumtype;
diff -cprN gcc-main-save/gcc/cp/name-lookup.c gcc-main-new/gcc/cp/name-lookup.c
*** gcc-main-save/gcc/cp/name-lookup.c	Sat Nov 27 00:05:57 2004
--- gcc-main-new/gcc/cp/name-lookup.c	Sat Nov 27 22:14:16 2004
*************** maybe_process_template_type_declaration 
*** 4566,4574 ****
  /* Push a tag name NAME for struct/class/union/enum type TYPE.
     Normally put it into the inner-most non-sk_cleanup scope,
     but if GLOBALIZE is true, put it in the inner-most non-class scope.
!    The latter is needed for implicit declarations.  */
  
! void
  pushtag (tree name, tree type, int globalize)
  {
    struct cp_binding_level *b;
--- 4566,4575 ----
  /* Push a tag name NAME for struct/class/union/enum type TYPE.
     Normally put it into the inner-most non-sk_cleanup scope,
     but if GLOBALIZE is true, put it in the inner-most non-class scope.
!    The latter is needed for implicit declarations.
!    Returns TYPE upon success and ERROR_MARK_NODE otherwise.  */
  
! tree
  pushtag (tree name, tree type, int globalize)
  {
    struct cp_binding_level *b;
*************** pushtag (tree name, tree type, int globa
*** 4633,4638 ****
--- 4634,4641 ----
  
  	  d = maybe_process_template_type_declaration (type,
  						       globalize, b);
+ 	  if (d == error_mark_node)
+ 	    return error_mark_node;
  
  	  if (b->kind == sk_class)
  	    {
*************** pushtag (tree name, tree type, int globa
*** 4695,4701 ****
        tree d = build_decl (TYPE_DECL, NULL_TREE, type);
        TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b);
      }
!   timevar_pop (TV_NAME_LOOKUP);
  }
  
  /* Subroutines for reverting temporarily to top-level for instantiation
--- 4698,4704 ----
        tree d = build_decl (TYPE_DECL, NULL_TREE, type);
        TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b);
      }
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
  }
  
  /* Subroutines for reverting temporarily to top-level for instantiation
diff -cprN gcc-main-save/gcc/cp/pt.c gcc-main-new/gcc/cp/pt.c
*** gcc-main-save/gcc/cp/pt.c	Sat Nov 27 00:00:57 2004
--- gcc-main-new/gcc/cp/pt.c	Sat Nov 27 22:12:52 2004
*************** push_template_decl_real (tree decl, int 
*** 3145,3151 ****
       parameters of the class.  */
    if (new_template_p && !ctx 
        && !(is_friend && template_class_depth (current_class_type) > 0))
!     tmpl = pushdecl_namespace_level (tmpl);
  
    if (primary)
      {
--- 3145,3155 ----
       parameters of the class.  */
    if (new_template_p && !ctx 
        && !(is_friend && template_class_depth (current_class_type) > 0))
!     {
!       tmpl = pushdecl_namespace_level (tmpl);
!       if (tmpl == error_mark_node)
! 	return error_mark_node;
!     }
  
    if (primary)
      {
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/lookup/crash6.C gcc-main-new/gcc/testsuite/g++.dg/lookup/crash6.C
*** gcc-main-save/gcc/testsuite/g++.dg/lookup/crash6.C	Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/lookup/crash6.C	Sat Nov 27 22:16:51 2004
***************
*** 0 ****
--- 1,8 ----
+ // { dg-do compile }
+ 
+ // Origin: Volker Reichelt <reichelt@gcc.gnu.org>
+ 
+ // PR c++/18652: ICE redeclaring variable as template.
+ 
+ int A;			// { dg-error "previous declaration" }
+ template<int> struct A; // { dg-error "different kind of symbol" }

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