OSDN Git Service

(push_init_level): For braces around scalar, just warn.
authorrms <rms@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Jul 1993 06:52:04 +0000 (06:52 +0000)
committerrms <rms@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Jul 1993 06:52:04 +0000 (06:52 +0000)
(process_init_element): Special handling for {"foo"}.
(struct constructor_stack): New field `replacement_value'.
(push_init_level, really_start_incremental_init): Clear new field.
(pop_init_level): Return the replacement_value if any.
At top level in initializer, output that value,
and set the array size from it.

(digest_init): Delete arg TAIL.  Fix all calls.

(convert_for_assignment): Mismatch in signedness
of pointer targets should not inhibit warnings for const mismatch.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@5042 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/c-typeck.c

index fe459d9..e4d4f24 100644 (file)
@@ -3899,7 +3899,7 @@ build_c_cast (type, expr)
            name = "";
          return digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE,
                                              build_tree_list (field, value)),
-                             NULL_PTR, 0, 0, name);
+                             0, 0);
        }
       error ("cast to union type from type not present in union");
       return error_mark_node;
@@ -4273,7 +4273,9 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
         Meanwhile, the lhs target must have all the qualifiers of the rhs.  */
       if (TYPE_MAIN_VARIANT (ttl) == void_type_node
          || TYPE_MAIN_VARIANT (ttr) == void_type_node
-         || comp_target_types (type, rhstype))
+         || comp_target_types (type, rhstype)
+         || (unsigned_type (TYPE_MAIN_VARIANT (ttl))
+             == unsigned_type (TYPE_MAIN_VARIANT (ttr))))
        {
          if (pedantic
              && ((TYPE_MAIN_VARIANT (ttl) == void_type_node
@@ -4292,9 +4294,19 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
              if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
                warn_for_assignment ("%s discards `const' from pointer target type",
                                     get_spelling (errtype), funname, parmnum);
-             if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
+             else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
                warn_for_assignment ("%s discards `volatile' from pointer target type",
                                     get_spelling (errtype), funname, parmnum);
+             /* If this is not a case of ignoring a mismatch in signedness,
+                no warning.  */
+             else if (TYPE_MAIN_VARIANT (ttl) == void_type_node
+                      || TYPE_MAIN_VARIANT (ttr) == void_type_node
+                      || comp_target_types (type, rhstype))
+               ;
+             /* If there is a mismatch, do warn.  */
+             else if (pedantic)
+               warn_for_assignment ("pointer targets in %s differ in signedness",
+                                    get_spelling (errtype), funname, parmnum);
            }
          else
            {
@@ -4310,13 +4322,6 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
                                     get_spelling (errtype), funname, parmnum);
            }
        }
-      else if (unsigned_type (TYPE_MAIN_VARIANT (ttl))
-              == unsigned_type (TYPE_MAIN_VARIANT (ttr)))
-       {
-         if (pedantic)
-           warn_for_assignment ("pointer targets in %s differ in signedness",
-                                get_spelling (errtype), funname, parmnum);
-       }
       else
        warn_for_assignment ("%s from incompatible pointer type",
                             get_spelling (errtype), funname, parmnum);
@@ -4536,9 +4541,8 @@ store_init_value (decl, init)
 
   /* Digest the specified initializer into an expression.  */
 
-  value = digest_init (type, init, NULL_PTR, TREE_STATIC (decl),
-                      TREE_STATIC (decl) || pedantic, 
-                      IDENTIFIER_POINTER (DECL_NAME (decl)));
+  value = digest_init (type, init, TREE_STATIC (decl),
+                      TREE_STATIC (decl) || pedantic);
 
   /* Store the expression if valid; else report error.  */
 
@@ -4832,8 +4836,8 @@ static tree free_tree_list = NULL_TREE;
    (That is true for all nested calls to digest_init.)  */
 
 static tree
-digest_init (type, init, tail, require_constant, constructor_constant)
-     tree type, init, *tail;
+digest_init (type, init, require_constant, constructor_constant)
+     tree type, init;
      int require_constant, constructor_constant;
 {
   enum tree_code code = TREE_CODE (type);
@@ -5156,6 +5160,9 @@ struct constructor_stack
   int offset;
   tree pending_elts;
   int depth;
+  /* If nonzero, this value should replace the entire
+     constructor at this level.  */
+  tree replacement_value;
   char constant;
   char simple;
   char implicit;
@@ -5319,6 +5326,7 @@ really_start_incremental_init (type)
   p->erroneous = constructor_erroneous;
   p->pending_elts = constructor_pending_elts;
   p->depth = constructor_depth;
+  p->replacement_value = 0;
   p->implicit = 0;
   p->incremental = constructor_incremental;
   p->outer = 0;
@@ -5400,6 +5408,7 @@ push_init_level (implicit)
   p->erroneous = constructor_erroneous;
   p->pending_elts = constructor_pending_elts;
   p->depth = constructor_depth;
+  p->replacement_value = 0;
   p->implicit = implicit;
   p->incremental = constructor_incremental;
   p->outer = 0;
@@ -5445,7 +5454,7 @@ push_init_level (implicit)
     }
   else
     {
-      error_init ("braces where a scalar is expected%s", " for `%s'", NULL);
+      warning ("braces around scalar initializer");
       constructor_fields = constructor_type;
       constructor_unfilled_fields = constructor_type;
     }
@@ -5513,7 +5522,50 @@ pop_init_level (implicit)
 
   /* Pad out the end of the structure.  */
   
-  if (! constructor_incremental)
+  if (p->replacement_value)
+    {
+      /* If this closes a superfluous brace pair,
+        just pass out the element between them.  */
+      constructor = p->replacement_value;
+      /* If this is the top level thing within the initializer,
+        and it's for a variable, then since we already calle
+        assemble_variable, we must output the value now.  */
+      if (p->next == 0 && constructor_decl != 0
+         && constructor_incremental)
+       {
+         constructor = digest_init (constructor_type, constructor,
+                                    0, 0);
+
+         /* If initializing an array of unknown size,
+            determine the size now.  */
+         if (TREE_CODE (constructor_type) == ARRAY_TYPE
+             && TYPE_DOMAIN (constructor_type) == 0)
+           {
+             int failure;
+
+             push_obstacks_nochange ();
+             if (TREE_PERMANENT (constructor_type))
+               end_temporary_allocation ();
+
+             /* We shouldn't have an incomplete array type within
+                some other type.  */
+             if (constructor_stack->next)
+               abort ();
+
+             failure
+               = complete_array_type (constructor_type,
+                                      constructor, 0);
+             if (failure)
+               abort ();
+
+             size = int_size_in_bytes (constructor_type);
+             pop_obstacks ();
+           }
+
+         output_constant (constructor, size);
+       }
+    }
+  else if (! constructor_incremental)
     {
       if (constructor_erroneous)
        constructor = error_mark_node;
@@ -5750,7 +5802,7 @@ output_init_element (value, type, field, pending)
       if (! duplicate)
        constructor_pending_elts
          = tree_cons (field,
-                      digest_init (type, value, (tree *)NULL,
+                      digest_init (type, value,
                                    require_constant_value,
                                    require_constant_elements),
                       constructor_pending_elts);
@@ -5762,7 +5814,7 @@ output_init_element (value, type, field, pending)
       if (!duplicate)
        constructor_pending_elts
          = tree_cons (field,
-                      digest_init (type, value, (tree *)NULL,
+                      digest_init (type, value,
                                    require_constant_value,
                                    require_constant_elements),
                       constructor_pending_elts);
@@ -5778,7 +5830,7 @@ output_init_element (value, type, field, pending)
            constructor_elements
              = tree_cons ((TREE_CODE (constructor_type) != ARRAY_TYPE
                            ? field : NULL),
-                          digest_init (type, value, (tree *)NULL,
+                          digest_init (type, value,
                                        require_constant_value,
                                        require_constant_elements),
                           constructor_elements);
@@ -5981,6 +6033,16 @@ process_init_element (value)
   tree orig_value = value;
   int string_flag = value != 0 && TREE_CODE (value) == STRING_CST;
 
+  /* Handle superfluous braces around string cst as in
+     char x[] = {"foo"}; */
+  if (string_flag
+      && TREE_CODE (constructor_type) == ARRAY_TYPE
+      && integer_zerop (constructor_unfilled_index))
+    {
+      constructor_stack->replacement_value = value;
+      return;
+    }
+
   if (value != 0)
     value = default_conversion (value);
 
@@ -5993,6 +6055,13 @@ process_init_element (value)
   else if (initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
     constructor_simple = 0;
 
+  if (constructor_stack->replacement_value != 0)
+    {
+      error_init ("excess elements in struct initializer%s",
+                 " after `%s'", NULL_PTR);
+      return;
+    }
+
   /* If we've exhausted any levels that didn't have braces,
      pop them now.  */
   while (constructor_stack->implicit)