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: PRs 10451, 9847


This patch fixes a couple of ice-on-illegal regressions in the C++
front end.

When confronted with two definitions of a single class, we tried to
make sense out of the second one, which is a complex and risky
proposition.  This patch removes the code that tried to do that, and
just ignores the second definition, which is far simpler.

Tested on i686-pc-linux-gnu, applied on the mainline.  After a bit
more testing, (a minor variant of) this patch will go on the branch as
well.

--
Mark Mitchell
CodeSourcery, LLC
mark at codesourcery dot com

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

	PR c++/10451
	* g++.dg/parse/crash4.C: New test.
	
	PR c++/9847
	* g++.dg/parse/crash5.C: New test.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.532
diff -c -5 -p -r1.532 class.c
*** cp/class.c	13 Apr 2003 01:45:29 -0000	1.532
--- cp/class.c	23 Apr 2003 16:20:15 -0000
*************** finish_struct_methods (tree t)
*** 1922,2003 ****
    if (len - slot > 1)
      qsort (&TREE_VEC_ELT (method_vec, slot), len-slot, sizeof (tree),
  	   method_name_cmp);
  }
  
- /* Emit error when a duplicate definition of a type is seen.  Patch up.  */
- 
- void
- duplicate_tag_error (tree t)
- {
-   error ("redefinition of `%#T'", t);
-   cp_error_at ("previous definition of `%#T'", t);
- 
-   /* Pretend we haven't defined this type.  */
- 
-   /* All of the component_decl's were TREE_CHAINed together in the parser.
-      finish_struct_methods walks these chains and assembles all methods with
-      the same base name into DECL_CHAINs. Now we don't need the parser chains
-      anymore, so we unravel them.  */
- 
-   /* This used to be in finish_struct, but it turns out that the
-      TREE_CHAIN is used by dbxout_type_methods and perhaps some other
-      things...  */
-   if (CLASSTYPE_METHOD_VEC (t)) 
-     {
-       tree method_vec = CLASSTYPE_METHOD_VEC (t);
-       int i, len  = TREE_VEC_LENGTH (method_vec);
-       for (i = 0; i < len; i++)
- 	{
- 	  tree unchain = TREE_VEC_ELT (method_vec, i);
- 	  while (unchain != NULL_TREE) 
- 	    {
- 	      TREE_CHAIN (OVL_CURRENT (unchain)) = NULL_TREE;
- 	      unchain = OVL_NEXT (unchain);
- 	    }
- 	}
-     }
- 
-   if (TYPE_LANG_SPECIFIC (t))
-     {
-       tree binfo = TYPE_BINFO (t);
-       int interface_only = CLASSTYPE_INTERFACE_ONLY (t);
-       int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t);
-       tree template_info = CLASSTYPE_TEMPLATE_INFO (t);
-       int use_template = CLASSTYPE_USE_TEMPLATE (t);
- 
-       memset ((char *) TYPE_LANG_SPECIFIC (t), 0, sizeof (struct lang_type));
-       BINFO_BASETYPES(binfo) = NULL_TREE;
- 
-       TYPE_LANG_SPECIFIC (t)->u.h.is_lang_type_class = 1;
-       TYPE_BINFO (t) = binfo;
-       CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
-       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
-       TYPE_REDEFINED (t) = 1;
-       CLASSTYPE_TEMPLATE_INFO (t) = template_info;
-       CLASSTYPE_USE_TEMPLATE (t) = use_template;
-       CLASSTYPE_DECL_LIST (t) = NULL_TREE;
-     }
-   TYPE_SIZE (t) = NULL_TREE;
-   TYPE_MODE (t) = VOIDmode;
-   TYPE_FIELDS (t) = NULL_TREE;
-   TYPE_METHODS (t) = NULL_TREE;
-   TYPE_VFIELD (t) = NULL_TREE;
-   TYPE_CONTEXT (t) = NULL_TREE;
-   
-   /* Clear TYPE_LANG_FLAGS -- those in TYPE_LANG_SPECIFIC are cleared above.  */
-   TYPE_LANG_FLAG_0 (t) = 0;
-   TYPE_LANG_FLAG_1 (t) = 0;
-   TYPE_LANG_FLAG_2 (t) = 0;
-   TYPE_LANG_FLAG_3 (t) = 0;
-   TYPE_LANG_FLAG_4 (t) = 0;
-   TYPE_LANG_FLAG_5 (t) = 0;
-   TYPE_LANG_FLAG_6 (t) = 0;
-   /* But not this one.  */
-   SET_IS_AGGR_TYPE (t, 1);
- }
- 
  /* Make BINFO's vtable have N entries, including RTTI entries,
     vbase and vcall offsets, etc.  Set its type and call the backend
     to lay it out.  */
  
  static void
--- 1922,1931 ----
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.838
diff -c -5 -p -r1.838 cp-tree.h
*** cp/cp-tree.h	22 Apr 2003 05:44:08 -0000	1.838
--- cp/cp-tree.h	23 Apr 2003 16:20:16 -0000
*************** extern void resort_sorted_fields 
*** 3538,3548 ****
  extern void resort_type_method_vec
    (void *, void *, gt_pointer_operator, void *);
  extern void add_method				(tree, tree, int);
  extern int currently_open_class			(tree);
  extern tree currently_open_derived_class	(tree);
- extern void duplicate_tag_error			(tree);
  extern tree finish_struct			(tree, tree);
  extern void finish_struct_1			(tree);
  extern int resolves_to_fixed_type_p		(tree, int *);
  extern void init_class_processing		(void);
  extern int is_empty_class			(tree);
--- 3538,3547 ----
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1039
diff -c -5 -p -r1.1039 decl.c
*** cp/decl.c	22 Apr 2003 21:05:57 -0000	1.1039
--- cp/decl.c	23 Apr 2003 16:20:20 -0000
*************** grokdeclarator (tree declarator,
*** 11042,11052 ****
        explicitp = 0;
      }
  
    if (RIDBIT_SETP (RID_MUTABLE, specbits))
      {
!       if (current_class_name == NULL_TREE || decl_context == PARM || friendp)
          {
  	  error ("non-member `%s' cannot be declared `mutable'", name);
            RIDBIT_RESET (RID_MUTABLE, specbits);
          }
        else if (decl_context == TYPENAME || RIDBIT_SETP (RID_TYPEDEF, specbits))
--- 11042,11052 ----
        explicitp = 0;
      }
  
    if (RIDBIT_SETP (RID_MUTABLE, specbits))
      {
!       if (decl_context != FIELD || friendp)
          {
  	  error ("non-member `%s' cannot be declared `mutable'", name);
            RIDBIT_RESET (RID_MUTABLE, specbits);
          }
        else if (decl_context == TYPENAME || RIDBIT_SETP (RID_TYPEDEF, specbits))
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.300
diff -c -5 -p -r1.300 semantics.c
*** cp/semantics.c	13 Apr 2003 01:45:33 -0000	1.300
--- cp/semantics.c	23 Apr 2003 16:20:26 -0000
*************** begin_class_definition (t)
*** 1795,1805 ****
      }
  
    /* If this type was already complete, and we see another definition,
       that's an error.  */
    if (COMPLETE_TYPE_P (t))
!     duplicate_tag_error (t);
  
    /* Update the location of the decl.  */
    DECL_SOURCE_FILE (TYPE_NAME (t)) = input_filename;
    DECL_SOURCE_LINE (TYPE_NAME (t)) = lineno;
    
--- 1795,1809 ----
      }
  
    /* If this type was already complete, and we see another definition,
       that's an error.  */
    if (COMPLETE_TYPE_P (t))
!     {
!       error ("redefinition of `%#T'", t);
!       cp_error_at ("previous definition of `%#T'", t);
!       return error_mark_node;
!     }
  
    /* Update the location of the decl.  */
    DECL_SOURCE_FILE (TYPE_NAME (t)) = input_filename;
    DECL_SOURCE_LINE (TYPE_NAME (t)) = lineno;
    
Index: testsuite/g++.dg/parse/crash4.C
===================================================================
RCS file: testsuite/g++.dg/parse/crash4.C
diff -N testsuite/g++.dg/parse/crash4.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/crash4.C	23 Apr 2003 16:20:28 -0000
***************
*** 0 ****
--- 1,12 ----
+ struct Bar
+  {
+      typedef int type;
+  };
+  
+  struct Foo
+  {
+      void func(void)
+      {
+        mutable Bar::type x; // { dg-error "" }
+      }
+  };
Index: testsuite/g++.dg/parse/crash5.C
===================================================================
RCS file: testsuite/g++.dg/parse/crash5.C
diff -N testsuite/g++.dg/parse/crash5.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/crash5.C	23 Apr 2003 16:20:28 -0000
***************
*** 0 ****
--- 1,13 ----
+ // { dg-options "-w" }
+ 
+ class QString { // { dg-error "" }
+   QString (const QString & a); // { dg-error "" }
+ };
+ 
+ class QString { }; // { dg-error "" }
+ 
+ const QString q () {
+   QString z; // { dg-error "" }
+   int x;
+   return x ? QString () : QString (); // { dg-error "" }
+ }


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