search.c (get_abstract_virtuals): Complain about virtuals with no final overrider.
authorJason Merrill <jason@yorick.cygnus.com>
Wed, 18 Nov 1998 02:21:54 +0000 (02:21 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 18 Nov 1998 02:21:54 +0000 (21:21 -0500)
* 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.
Fixes Sec10/3/E10120.C
* lex.c (reinit_parse_for_block): Add a space after the initial ':'.
Fixes Sec9/7/R09434.r0
* class.c (finish_struct_1): Don't remove zero-width bit-fields until
after layout_type.
Fixes Sec9/6/P09024.C
* friend.c (do_friend): Don't set_mangled_name_for_decl.
Fixes Sec9/2/P09075.C
* 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.
Fixes Sec9/2/C09268.cm

From-SVN: r23691

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/friend.c
gcc/cp/lex.c
gcc/cp/search.c
gcc/cp/typeck2.c

index 1102b9e..777848c 100644 (file)
@@ -1,3 +1,27 @@
+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.
+
 1998-11-17  Mark Mitchell  <mark@markmitchell.com>
 
        * cp-tree.h (TYPE_ALIAS_SET): Document language-dependent uses.
 1998-11-17  Mark Mitchell  <mark@markmitchell.com>
 
        * cp-tree.h (TYPE_ALIAS_SET): Document language-dependent uses.
index 7668697..b25dbef 100644 (file)
@@ -2858,13 +2858,11 @@ override_one_vtable (binfo, old, t)
            }
          {
            /* This MUST be overridden, or the class is ill-formed.  */
            }
          {
            /* 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);
            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))
            DECL_NEEDS_FINAL_OVERRIDER_P (fndecl) = 1;
            /* Make sure we search for it later.  */
            if (! CLASSTYPE_ABSTRACT_VIRTUALS (t))
@@ -3142,9 +3140,20 @@ finish_struct_anon (t)
          tree* uelt = &TYPE_FIELDS (TREE_TYPE (field));
          for (; *uelt; uelt = &TREE_CHAIN (*uelt))
            {
          tree* uelt = &TYPE_FIELDS (TREE_TYPE (field));
          for (; *uelt; uelt = &TREE_CHAIN (*uelt))
            {
-             if (TREE_CODE (*uelt) != FIELD_DECL)
+             if (DECL_ARTIFICIAL (*uelt))
                continue;
 
                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);
              if (TREE_PRIVATE (*uelt))
                cp_pedwarn_at ("private member `%#D' in anonymous union",
                               *uelt);
@@ -3885,23 +3894,9 @@ finish_struct_1 (t, warn_anon)
     }
 
   /* Now DECL_INITIAL is null on all members except for zero-width bit-fields.
     }
 
   /* 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...  */
 
 
      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);
 
   /* Delete all duplicate fields from the fields */
   delete_duplicate_fields (fields);
 
@@ -3931,7 +3926,7 @@ finish_struct_1 (t, warn_anon)
        }
     }
 
        }
     }
 
-  /* Now we have the final fieldlist for the data fields.  Record it,
+  /* 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;
      then lay out the structure or union (including the fields).  */
 
   TYPE_FIELDS (t) = fields;
@@ -3988,6 +3983,23 @@ finish_struct_1 (t, warn_anon)
   else if (empty)
     TYPE_FIELDS (t) = fields;
 
   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))
     {
       tree vbases;
   if (TYPE_USES_VIRTUAL_BASECLASSES (t))
     {
       tree vbases;
index bd8c5c8..dd7fba9 100644 (file)
@@ -10779,13 +10779,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  return void_type_node;
              }
 
                  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)
              {
            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.
                /* 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 cad6078..c2b4a1d 100644 (file)
@@ -2141,8 +2141,15 @@ build_anon_union_vars (anon_decl, elems, static_p, external_p)
        field = TREE_CHAIN (field))
     {
       tree decl;
        field = TREE_CHAIN (field))
     {
       tree decl;
-      if (TREE_CODE (field) != FIELD_DECL)
+
+      if (DECL_ARTIFICIAL (field))
        continue;
        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);
 
       if (TREE_PRIVATE (field))
        cp_pedwarn_at ("private member `%#D' in anonymous union", field);
index 81b67a5..0b71f09 100644 (file)
@@ -413,7 +413,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
 
         Note that because classes all wind up being top-level
         in their scope, their friend wind up in top-level scope as well.  */
 
         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;
       DECL_ARGUMENTS (decl) = parmdecls;
       if (funcdef_flag)
        DECL_CLASS_CONTEXT (decl) = current_class_type;
index 5bbb966..5d60b04 100644 (file)
@@ -1554,6 +1554,8 @@ reinit_parse_for_block (pyychar, obstackp)
   else if (pyychar == ':')
     {
       obstack_1grow (obstackp, pyychar);
   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;
     }
       look_for_lbrac = 1;
       blev = 0;
     }
index ee44bba..1f70579 100644 (file)
@@ -1963,7 +1963,9 @@ get_abstract_virtuals (type)
        {
          tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals));
          tree base_fndecl = TREE_OPERAND (base_pfn, 0);
        {
          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))
+         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);
        }
            abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals);
          virtuals = TREE_CHAIN (virtuals);
        }
index 8766925..78eebf6 100644 (file)
@@ -133,30 +133,8 @@ abstract_virtuals_error (decl, type)
      tree type;
 {
   tree u = CLASSTYPE_ABSTRACT_VIRTUALS (type);
      tree type;
 {
   tree u = CLASSTYPE_ABSTRACT_VIRTUALS (type);
-  int has_abstract_virtuals, needs_final_overriders;
   tree tu;
 
   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)
   if (decl)
     {
       if (TREE_CODE (decl) == RESULT_DECL)
@@ -185,44 +163,12 @@ abstract_virtuals_error (decl, type)
     {
       TREE_PURPOSE (u) = error_mark_node;
 
     {
       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);
-       }
+      error ("  since the following virtual functions are abstract:");
+      for (tu = u; tu; tu = TREE_CHAIN (tu))
+       cp_error ("\t%#D", TREE_VALUE (tu));
     }
   else
     }
   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);
-    }
+    cp_error ("  since type `%T' has abstract virtual functions", type);
 }
 
 /* Print an error message for invalid use of a signature type.
 }
 
 /* Print an error message for invalid use of a signature type.