typeck2.c (process_init_constructor): If there are elements that don't have initializ...
authorJason Merrill <jason@yorick.cygnus.com>
Mon, 23 Nov 1998 23:57:32 +0000 (23:57 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 23 Nov 1998 23:57:32 +0000 (18:57 -0500)
* typeck2.c (process_init_constructor): If there are elements
that don't have initializers and they need to have constructors
run, supply them with initializers.
Fixes Sec12/6_1/P12176.C.
* class.c (finish_struct_1): A class with a 0-width bitfield is
still empty.
Fixes Sec9/6/R09387.r0.  Really this time.

From-SVN: r23819

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/typeck2.c

index ff7f563..6e40336 100644 (file)
@@ -1,3 +1,12 @@
+1998-11-23  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * typeck2.c (process_init_constructor): If there are elements
+       that don't have initializers and they need to have constructors
+       run, supply them with initializers.
+
+       * class.c (finish_struct_1): A class with a 0-width bitfield is
+       still empty.
+
 1998-11-23  Mark Mitchell  <mark@markmitchell.com>
 
        * pt.c (instantiate_class_template): Don't try to figure out what
index 1c2ec6b..de283ea 100644 (file)
@@ -1235,7 +1235,9 @@ add_method (type, fields, method)
                }
            }
 
-         if (DECL_CONV_FN_P (method))
+         if (TREE_VEC_ELT (method_vec, i))
+           /* We found a match.  */;
+         else if (DECL_CONV_FN_P (method))
            {
              /* Type conversion operators have to come before
                 ordinary methods; add_conversions depends on this to
@@ -3453,7 +3455,11 @@ finish_struct_1 (t, warn_anon)
       if (TREE_CODE (x) == FIELD_DECL)
        {
          DECL_PACKED (x) |= TYPE_PACKED (t);
-         empty = 0;
+
+         if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
+           /* A zero-width bitfield doesn't do the trick.  */;
+         else
+           empty = 0;
        }
 
       if (TREE_CODE (x) == USING_DECL)
index 4e490bf..e11bde2 100644 (file)
@@ -703,6 +703,9 @@ digest_init (type, init, tail)
   if (TREE_CODE (init) == NON_LVALUE_EXPR)
     init = TREE_OPERAND (init, 0);
 
+  if (TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == type)
+    return init;
+
   raw_constructor = TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == 0;
 
   if (raw_constructor
@@ -873,6 +876,7 @@ process_init_constructor (type, init, elts)
   /* List of the elements of the result constructor,
      in reverse order.  */
   register tree members = NULL;
+  register tree next1;
   tree result;
   int allconstant = 1;
   int allsimple = 1;
@@ -907,42 +911,59 @@ process_init_constructor (type, init, elts)
       else
        len = -1;  /* Take as many as there are */
 
-      for (i = 0; (len < 0 || i < len) && tail != 0; i++)
+      for (i = 0; len < 0 || i < len; i++)
        {
-         register tree next1;
-
-         if (TREE_PURPOSE (tail)
-             && (TREE_CODE (TREE_PURPOSE (tail)) != INTEGER_CST
-                 || TREE_INT_CST_LOW (TREE_PURPOSE (tail)) != i))
-           sorry ("non-trivial labeled initializers");
-
-         if (TREE_VALUE (tail) != 0)
+         if (tail)
            {
-             tree tail1 = tail;
-             next1 = digest_init (TREE_TYPE (type),
-                                  TREE_VALUE (tail), &tail1);
-             if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type))
-                 && TYPE_MAIN_VARIANT (TREE_TYPE (type)) != TYPE_MAIN_VARIANT (TREE_TYPE (next1)))
+             if (TREE_PURPOSE (tail)
+                 && (TREE_CODE (TREE_PURPOSE (tail)) != INTEGER_CST
+                     || TREE_INT_CST_LOW (TREE_PURPOSE (tail)) != i))
+               sorry ("non-trivial labeled initializers");
+
+             if (TREE_VALUE (tail) != 0)
                {
-                 /* The fact this needs to be done suggests this code needs
-                    to be totally rewritten.  */
-                 next1 = convert_for_initialization (NULL_TREE, TREE_TYPE (type), next1, LOOKUP_NORMAL, "initialization", NULL_TREE, 0);
+                 tree tail1 = tail;
+                 next1 = digest_init (TREE_TYPE (type),
+                                      TREE_VALUE (tail), &tail1);
+                 my_friendly_assert (TYPE_MAIN_VARIANT (TREE_TYPE (type))
+                                     == TYPE_MAIN_VARIANT (TREE_TYPE (next1)),
+                                     981123);
+                 my_friendly_assert (tail1 == 0
+                                     || TREE_CODE (tail1) == TREE_LIST, 319);
+                 if (tail == tail1 && len < 0)
+                   {
+                     error ("non-empty initializer for array of empty elements");
+                     /* Just ignore what we were supposed to use.  */
+                     tail1 = NULL_TREE;
+                   }
+                 tail = tail1;
                }
-             my_friendly_assert (tail1 == 0
-                                 || TREE_CODE (tail1) == TREE_LIST, 319);
-             if (tail == tail1 && len < 0)
+             else
                {
-                 error ("non-empty initializer for array of empty elements");
-                 /* Just ignore what we were supposed to use.  */
-                 tail1 = NULL_TREE;
+                 next1 = error_mark_node;
+                 tail = TREE_CHAIN (tail);
                }
-             tail = tail1;
            }
-         else
+         else if (len < 0)
+           /* We're done.  */
+           break;
+         else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type)))
            {
-             next1 = error_mark_node;
-             tail = TREE_CHAIN (tail);
+             /* If this type needs constructors run for
+                default-initialization, we can't rely on the backend to do it
+                for us, so build up TARGET_EXPRs.  If the type in question is
+                a class, just build one up; if it's an array, recurse.  */
+
+             if (IS_AGGR_TYPE (TREE_TYPE (type)))
+               next1 = build_functional_cast (TREE_TYPE (type), NULL_TREE);
+             else
+               next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
+             next1 = digest_init (TREE_TYPE (type), next1, 0);
            }
+         else
+           /* The default zero-initialization is fine for us; don't
+              add anything to the CONSTRUCTOR.  */
+           break;
 
          if (next1 == error_mark_node)
            erroneous = 1;
@@ -978,11 +999,9 @@ process_init_constructor (type, init, elts)
            }
        }
 
-      for (field = TYPE_FIELDS (type); field && tail;
+      for (field = TYPE_FIELDS (type); field;
           field = TREE_CHAIN (field))
        {
-         register tree next1;
-
          if (! DECL_NAME (field) && DECL_C_BIT_FIELD (field))
            {
              members = expr_tree_cons (field, integer_zero_node, members);
@@ -992,25 +1011,67 @@ process_init_constructor (type, init, elts)
          if (TREE_CODE (field) != FIELD_DECL)
            continue;
 
-         if (TREE_PURPOSE (tail)
-             && TREE_PURPOSE (tail) != field
-             && TREE_PURPOSE (tail) != DECL_NAME (field))
-           sorry ("non-trivial labeled initializers");
+         if (tail)
+           {
+             if (TREE_PURPOSE (tail)
+                 && TREE_PURPOSE (tail) != field
+                 && TREE_PURPOSE (tail) != DECL_NAME (field))
+               sorry ("non-trivial labeled initializers");
+
+             if (TREE_VALUE (tail) != 0)
+               {
+                 tree tail1 = tail;
 
-         if (TREE_VALUE (tail) != 0)
+                 next1 = digest_init (TREE_TYPE (field),
+                                      TREE_VALUE (tail), &tail1);
+                 my_friendly_assert (tail1 == 0
+                                     || TREE_CODE (tail1) == TREE_LIST, 320);
+                 tail = tail1;
+               }
+             else
+               {
+                 next1 = error_mark_node;
+                 tail = TREE_CHAIN (tail);
+               }
+           }
+         else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
            {
-             tree tail1 = tail;
+             /* If this type needs constructors run for
+                default-initialization, we can't rely on the backend to do it
+                for us, so build up TARGET_EXPRs.  If the type in question is
+                a class, just build one up; if it's an array, recurse.  */
+
+             if (IS_AGGR_TYPE (TREE_TYPE (field)))
+               next1 = build_functional_cast (TREE_TYPE (field),
+                                              NULL_TREE);
+             else
+               next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE,
+                              NULL_TREE);
+             next1 = digest_init (TREE_TYPE (field), next1, 0);
 
-             next1 = digest_init (TREE_TYPE (field),
-                                  TREE_VALUE (tail), &tail1);
-             my_friendly_assert (tail1 == 0
-                                 || TREE_CODE (tail1) == TREE_LIST, 320);
-             tail = tail1;
+             /* Warn when some struct elements are implicitly initialized.  */
+             if (extra_warnings)
+               cp_warning ("missing initializer for member `%D'", field);
            }
          else
            {
-             next1 = error_mark_node;
-             tail = TREE_CHAIN (tail);
+             if (TREE_READONLY (field))
+               cp_error ("uninitialized const member `%D'", field);
+             else if (TYPE_LANG_SPECIFIC (TREE_TYPE (field))
+                      && CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field)))
+               cp_error ("member `%D' with uninitialized const fields",
+                         field);
+             else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
+               cp_error ("member `%D' is uninitialized reference", field);
+
+             /* Warn when some struct elements are implicitly initialized
+                to zero.  */
+             if (extra_warnings)
+               cp_warning ("missing initializer for member `%D'", field);
+
+             /* The default zero-initialization is fine for us; don't
+                add anything to the CONSTRUCTOR.  */
+             continue;
            }
 
          if (next1 == error_mark_node)
@@ -1021,44 +1082,10 @@ process_init_constructor (type, init, elts)
            allsimple = 0;
          members = expr_tree_cons (field, next1, members);
        }
-      for (; field; field = TREE_CHAIN (field))
-       {
-         if (TREE_CODE (field) != FIELD_DECL)
-           continue;
-
-         /* Does this field have a default initialization?  */
-         if (DECL_INITIAL (field))
-           {
-             register tree next1 = DECL_INITIAL (field);
-             if (TREE_CODE (next1) == ERROR_MARK)
-               erroneous = 1;
-             else if (!TREE_CONSTANT (next1))
-               allconstant = 0;
-             else if (! initializer_constant_valid_p (next1, TREE_TYPE (next1)))
-               allsimple = 0;
-             members = expr_tree_cons (field, next1, members);
-           }
-         else if (TREE_READONLY (field))
-           error ("uninitialized const member `%s'",
-                  IDENTIFIER_POINTER (DECL_NAME (field)));
-         else if (TYPE_LANG_SPECIFIC (TREE_TYPE (field))
-                  && CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field)))
-           error ("member `%s' with uninitialized const fields",
-                  IDENTIFIER_POINTER (DECL_NAME (field)));
-         else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
-           error ("member `%s' is uninitialized reference",
-                  IDENTIFIER_POINTER (DECL_NAME (field)));
-         /* Warn when some struct elements are implicitly initialized
-             to zero.  */
-         else if (extra_warnings)
-           warning ("missing initializer for member `%s'",
-                    IDENTIFIER_POINTER (DECL_NAME (field)));
-       }
     }
   else if (TREE_CODE (type) == UNION_TYPE)
     {
       register tree field = TYPE_FIELDS (type);
-      register tree next1;
 
       /* Find the first named field.  ANSI decided in September 1990
         that only named fields count here.  */
@@ -1087,8 +1114,8 @@ process_init_constructor (type, init, elts)
              if (temp)
                field = temp, win = 1;
              else
-               error ("no field `%s' in union being initialized",
-                      IDENTIFIER_POINTER (TREE_PURPOSE (tail)));
+               cp_error ("no field `%D' in union being initialized",
+                         TREE_PURPOSE (tail));
            }
          if (!win)
            TREE_VALUE (tail) = error_mark_node;