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]

(C++) the next batch of patches


I'm surprised nobody noticed before that zero-width bitfields were
ignored.  I guess they aren't used that much.

1998-11-18  Jason Merrill  <jason@yorick.cygnus.com>

	* search.c (get_abstract_virtuals): Complain about virtuals with
	no final overrider.
	* typeck2.c (abstract_virtuals_error): Remove handling for virtuals
	with no final overrider.
	* class.c (override_one_vtable): Don't set DECL_ABSTRACT_VIRTUAL_P
	on virtuals with no final overrider.

	* lex.c (reinit_parse_for_block): Add a space after the initial ':'.

	* class.c (finish_struct_1): Don't remove zero-width bit-fields until
	after layout_type.

	* friend.c (do_friend): Don't set_mangled_name_for_decl.

	* class.c (finish_struct_anon): Complain about non-fields.
	* decl2.c (build_anon_union_vars): Likewise.

	* decl.c (grokdeclarator): Normal data members can't have the same
	name as the class, either.
	* class.c (finish_struct_anon): Neither can members of an
	anonymous union.

Index: class.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/class.c,v
retrieving revision 1.105
diff -c -p -r1.105 class.c
*** class.c	1998/11/03 17:37:46	1.105
--- class.c	1998/11/18 10:15:58
*************** override_one_vtable (binfo, old, t)
*** 2852,2864 ****
  	    }
  	  {
  	    /* This MUST be overridden, or the class is ill-formed.  */
- 	    /* For now, we just make it abstract.  */
  	    tree fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);
  	    tree vfn;
  
  	    fndecl = copy_node (fndecl);
  	    copy_lang_decl (fndecl);
- 	    DECL_ABSTRACT_VIRTUAL_P (fndecl) = 1;
  	    DECL_NEEDS_FINAL_OVERRIDER_P (fndecl) = 1;
  	    /* Make sure we search for it later.  */
  	    if (! CLASSTYPE_ABSTRACT_VIRTUALS (t))
--- 2852,2862 ----
*************** finish_struct_anon (t)
*** 3136,3144 ****
  	  tree* uelt = &TYPE_FIELDS (TREE_TYPE (field));
  	  for (; *uelt; uelt = &TREE_CHAIN (*uelt))
  	    {
! 	      if (TREE_CODE (*uelt) != FIELD_DECL)
  		continue;
  
  	      if (TREE_PRIVATE (*uelt))
  		cp_pedwarn_at ("private member `%#D' in anonymous union",
  			       *uelt);
--- 3134,3153 ----
  	  tree* uelt = &TYPE_FIELDS (TREE_TYPE (field));
  	  for (; *uelt; uelt = &TREE_CHAIN (*uelt))
  	    {
! 	      if (DECL_ARTIFICIAL (*uelt))
  		continue;
  
+ 	      if (DECL_NAME (*uelt) == TYPE_IDENTIFIER (t))
+ 		cp_pedwarn_at ("ANSI C++ forbids member `%D' with same name as enclosing class",
+ 			       *uelt);
+ 
+ 	      if (TREE_CODE (*uelt) != FIELD_DECL)
+ 		{
+ 		  cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members",
+ 				 *uelt);
+ 		  continue;
+ 		}
+ 
  	      if (TREE_PRIVATE (*uelt))
  		cp_pedwarn_at ("private member `%#D' in anonymous union",
  			       *uelt);
*************** finish_struct_1 (t, warn_anon)
*** 3879,3901 ****
      }
  
    /* Now DECL_INITIAL is null on all members except for zero-width bit-fields.
-      And they have already done their work.
  
       C++: maybe we will support default field initialization some day...  */
  
-   /* Delete all zero-width bit-fields from the front of the fieldlist */
-   while (fields && DECL_C_BIT_FIELD (fields)
- 	 && DECL_INITIAL (fields))
-     fields = TREE_CHAIN (fields);
-   /* Delete all such fields from the rest of the fields.  */
-   for (x = fields; x;)
-     {
-       if (TREE_CHAIN (x) && DECL_C_BIT_FIELD (TREE_CHAIN (x))
- 	  && DECL_INITIAL (TREE_CHAIN (x)))
- 	TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
-       else
- 	x = TREE_CHAIN (x);
-     }
    /* Delete all duplicate fields from the fields */
    delete_duplicate_fields (fields);
  
--- 3888,3896 ----
*************** finish_struct_1 (t, warn_anon)
*** 3925,3931 ****
  	}
      }
  
!   /* Now we have the final fieldlist for the data fields.  Record it,
       then lay out the structure or union (including the fields).  */
  
    TYPE_FIELDS (t) = fields;
--- 3920,3926 ----
  	}
      }
  
!   /* Now we have the nearly final fieldlist for the data fields.  Record it,
       then lay out the structure or union (including the fields).  */
  
    TYPE_FIELDS (t) = fields;
*************** finish_struct_1 (t, warn_anon)
*** 3981,3986 ****
--- 3976,3998 ----
      max_has_virtual = layout_basetypes (t, max_has_virtual);
    else if (empty)
      TYPE_FIELDS (t) = fields;
+ 
+   my_friendly_assert (TYPE_FIELDS (t) == fields, 981117);
+ 
+   /* Delete all zero-width bit-fields from the front of the fieldlist */
+   while (fields && DECL_C_BIT_FIELD (fields)
+ 	 && DECL_INITIAL (fields))
+     fields = TREE_CHAIN (fields);
+   /* Delete all such fields from the rest of the fields.  */
+   for (x = fields; x;)
+     {
+       if (TREE_CHAIN (x) && DECL_C_BIT_FIELD (TREE_CHAIN (x))
+ 	  && DECL_INITIAL (TREE_CHAIN (x)))
+ 	TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
+       else
+ 	x = TREE_CHAIN (x);
+     }
+   TYPE_FIELDS (t) = fields;
  
    if (TYPE_USES_VIRTUAL_BASECLASSES (t))
      {
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.260
diff -c -p -r1.260 decl.c
*** decl.c	1998/11/16 08:33:58	1.260
--- decl.c	1998/11/18 10:15:59
*************** grokdeclarator (declarator, declspecs, d
*** 10717,10729 ****
  		  return void_type_node;
  	      }
  
  	    if (staticp)
  	      {
- 		/* ANSI C++ Apr '95 wp 9.2 */
- 		if (declarator == current_class_name)
- 		  cp_pedwarn ("ANSI C++ forbids static member `%D' with same name as enclosing class",
- 			      declarator);
- 
  		/* C++ allows static class members.
  		   All other work for this is done by grokfield.
  		   This VAR_DCL is built by build_lang_field_decl.
--- 10717,10729 ----
  		  return void_type_node;
  	      }
  
+ 	    /* 9.2p13 [class.mem] */
+ 	    if (declarator == current_class_name)
+ 	      cp_pedwarn ("ANSI C++ forbids data member `%D' with same name as enclosing class",
+ 			  declarator);
+ 
  	    if (staticp)
  	      {
  		/* C++ allows static class members.
  		   All other work for this is done by grokfield.
  		   This VAR_DCL is built by build_lang_field_decl.
Index: decl2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl2.c,v
retrieving revision 1.154
diff -c -p -r1.154 decl2.c
*** decl2.c	1998/11/03 17:37:49	1.154
--- decl2.c	1998/11/18 10:15:59
*************** build_anon_union_vars (anon_decl, elems,
*** 2141,2148 ****
         field = TREE_CHAIN (field))
      {
        tree decl;
!       if (TREE_CODE (field) != FIELD_DECL)
  	continue;
  
        if (TREE_PRIVATE (field))
  	cp_pedwarn_at ("private member `%#D' in anonymous union", field);
--- 2141,2155 ----
         field = TREE_CHAIN (field))
      {
        tree decl;
! 
!       if (DECL_ARTIFICIAL (field))
  	continue;
+       if (TREE_CODE (field) != FIELD_DECL)
+ 	{
+ 	  cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members",
+ 			 field);
+ 	  continue;
+ 	}
  
        if (TREE_PRIVATE (field))
  	cp_pedwarn_at ("private member `%#D' in anonymous union", field);
Index: friend.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/friend.c,v
retrieving revision 1.35
diff -c -p -r1.35 friend.c
*** friend.c	1998/11/01 15:45:03	1.35
--- friend.c	1998/11/18 10:15:59
*************** do_friend (ctype, declarator, decl, parm
*** 413,419 ****
  
  	 Note that because classes all wind up being top-level
  	 in their scope, their friend wind up in top-level scope as well.  */
-       set_mangled_name_for_decl (decl);
        DECL_ARGUMENTS (decl) = parmdecls;
        if (funcdef_flag)
  	DECL_CLASS_CONTEXT (decl) = current_class_type;
--- 413,418 ----
Index: lex.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/lex.c,v
retrieving revision 1.83
diff -c -p -r1.83 lex.c
*** lex.c	1998/10/29 11:55:06	1.83
--- lex.c	1998/11/18 10:15:59
*************** reinit_parse_for_block (pyychar, obstack
*** 1554,1559 ****
--- 1554,1561 ----
    else if (pyychar == ':')
      {
        obstack_1grow (obstackp, pyychar);
+       /* Add a space so we don't get confused by ': ::A(20)'.  */
+       obstack_1grow (obstackp, ' ');
        look_for_lbrac = 1;
        blev = 0;
      }
Index: search.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/search.c,v
retrieving revision 1.66
diff -c -p -r1.66 search.c
*** search.c	1998/11/11 03:42:37	1.66
--- search.c	1998/11/18 10:15:59
*************** get_abstract_virtuals (type)
*** 1962,1968 ****
  	{
  	  tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals));
  	  tree base_fndecl = TREE_OPERAND (base_pfn, 0);
! 	  if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl))
  	    abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals);
  	  virtuals = TREE_CHAIN (virtuals);
  	}
--- 1962,1970 ----
  	{
  	  tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals));
  	  tree base_fndecl = TREE_OPERAND (base_pfn, 0);
! 	  if (DECL_NEEDS_FINAL_OVERRIDER_P (base_fndecl))
! 	    cp_error ("`%#D' needs a final overrider", base_fndecl);
! 	  else if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl))
  	    abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals);
  	  virtuals = TREE_CHAIN (virtuals);
  	}
Index: typeck2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck2.c,v
retrieving revision 1.41
diff -c -p -r1.41 typeck2.c
*** typeck2.c	1998/11/16 20:45:16	1.41
--- typeck2.c	1998/11/18 10:15:59
*************** abstract_virtuals_error (decl, type)
*** 133,162 ****
       tree type;
  {
    tree u = CLASSTYPE_ABSTRACT_VIRTUALS (type);
-   int has_abstract_virtuals, needs_final_overriders;
    tree tu;
  
-   /* Count how many abstract methods need to be defined.  */
-   for (has_abstract_virtuals = 0, tu = u; tu; tu = TREE_CHAIN (tu))
-     {
-       if (DECL_ABSTRACT_VIRTUAL_P (TREE_VALUE (tu))
- 	  && ! DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
- 	{
- 	  has_abstract_virtuals = 1;
- 	  break;
- 	}
-     }
- 
-   /* Count how many virtual methods need a final overrider.  */
-   for (needs_final_overriders = 0, tu = u; tu; tu = TREE_CHAIN (tu))
-     {
-       if (DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
- 	{
- 	  needs_final_overriders = 1;
- 	  break;
- 	}
-     }
- 
    if (decl)
      {
        if (TREE_CODE (decl) == RESULT_DECL)
--- 133,140 ----
*************** abstract_virtuals_error (decl, type)
*** 184,228 ****
    if (TREE_PURPOSE (u) == NULL_TREE)
      {
        TREE_PURPOSE (u) = error_mark_node;
- 
-       if (has_abstract_virtuals)
- 	error ("  since the following virtual functions are abstract:");
-       tu = u;
-       while (tu)
- 	{
- 	  if (DECL_ABSTRACT_VIRTUAL_P (TREE_VALUE (tu))
- 	      && ! DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
- 	    cp_error ("\t%#D", TREE_VALUE (tu));
- 	  tu = TREE_CHAIN (tu);
- 	}
  
!       if (needs_final_overriders)
! 	{
! 	  if (has_abstract_virtuals)
! 	    error ("  and the following virtual functions need a final overrider:");
! 	  else
! 	    error ("  since the following virtual functions need a final overrider:");
! 	}
!       tu = u;
!       while (tu)
! 	{
! 	  if (DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
! 	    cp_error ("\t%#D", TREE_VALUE (tu));
! 	  tu = TREE_CHAIN (tu);
! 	}
      }
    else
!     {
!       if (has_abstract_virtuals)
! 	{
! 	  if (needs_final_overriders)
! 	    cp_error ("  since type `%T' has abstract virtual functions and must override virtual functions", type);
! 	  else
! 	    cp_error ("  since type `%T' has abstract virtual functions", type);
! 	}
!       else
! 	cp_error ("  since type `%T' must override virtual functions", type);
!     }
  }
  
  /* Print an error message for invalid use of a signature type.
--- 162,174 ----
    if (TREE_PURPOSE (u) == NULL_TREE)
      {
        TREE_PURPOSE (u) = error_mark_node;
  
!       error ("  since the following virtual functions are abstract:");
!       for (tu = u; tu; tu = TREE_CHAIN (tu))
! 	cp_error ("\t%#D", TREE_VALUE (tu));
      }
    else
!     cp_error ("  since type `%T' has abstract virtual functions", type);
  }
  
  /* Print an error message for invalid use of a signature type.


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