re PR c/20519 (completed type not selected properly with typeof)
authorRichard Henderson <rth@redhat.com>
Wed, 30 Mar 2005 01:35:15 +0000 (17:35 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 30 Mar 2005 01:35:15 +0000 (17:35 -0800)
        PR c/20519
        * c-decl.c (c_finish_incomplete_decl): Update complete_array_type call.
        (build_compound_literal): Likewise.  Propagate decl type into the
        initializer.
        (finish_decl): Likewise.  Use new return value from complete_array_type
        for zero sized arrays.
        (complete_array_type): Move ...
        * c-common.c (complete_array_type): ... here.  Change first argument
        to pointer-to-type-node.  Consistently use sizetype for the index
        except for zero sized arrays.  Detect zero sized arrays for pedantic
        mode diagnostics.  Create a new type node instead of modifying the
        old node in place.
        * c-tree.h (complete_array_type): Move decl ...
        * c-common.h (complete_array_type): ... here.
cp/
        * decl.c (cp_complete_array_type): Rename from complete_array_type.
        Use the new complete_array_type in c-common.c.  Update all callers.
        * cp-tree.h (cp_complete_array_type): Update to match.

From-SVN: r97223

gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-decl.c
gcc/c-tree.h
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/semantics.c
gcc/cp/typeck2.c

index e3e54f8c0a8db33b7e6ac6719e8944b2db0a09e0..fbd8351723a4084c69b23f83e5fbc7da39369482 100644 (file)
@@ -1,3 +1,20 @@
+2005-03-29  Richard Henderson  <rth@redhat.com>
+
+       PR c/20519
+       * c-decl.c (c_finish_incomplete_decl): Update complete_array_type call.
+       (build_compound_literal): Likewise.  Propagate decl type into the
+       initializer.
+       (finish_decl): Likewise.  Use new return value from complete_array_type
+       for zero sized arrays.
+       (complete_array_type): Move ...
+       * c-common.c (complete_array_type): ... here.  Change first argument
+       to pointer-to-type-node.  Consistently use sizetype for the index
+       except for zero sized arrays.  Detect zero sized arrays for pedantic
+       mode diagnostics.  Create a new type node instead of modifying the
+       old node in place.
+       * c-tree.h (complete_array_type): Move decl ...
+       * c-common.h (complete_array_type): ... here.
+
 2005-03-29  Richard Henderson  <rth@redhat.com>
 
        PR tree-opt/19108
index ec7b04d6f325baebf03552285dfa668e66a89ee6..5705f4d1eb282f76476d30990a236910fbb51b60 100644 (file)
@@ -5756,5 +5756,94 @@ lvalue_error (enum lvalue_use use)
       gcc_unreachable ();
     }
 }
+\f
+/* *PTYPE is an incomplete array.  Complete it with a domain based on
+   INITIAL_VALUE.  If INITIAL_VALUE is not present, use 1 if DO_DEFAULT
+   is true.  Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
+   2 if INITIAL_VALUE was NULL, and 3 if INITIAL_VALUE was empty.  */
+
+int
+complete_array_type (tree *ptype, tree initial_value, bool do_default)
+{
+  tree maxindex, type, main_type, elt, unqual_elt;
+  int failure = 0, quals;
+
+  maxindex = size_zero_node;
+  if (initial_value)
+    {
+      if (TREE_CODE (initial_value) == STRING_CST)
+       {
+         int eltsize
+           = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
+         maxindex = size_int (TREE_STRING_LENGTH (initial_value)/eltsize - 1);
+       }
+      else if (TREE_CODE (initial_value) == CONSTRUCTOR)
+       {
+         tree elts = CONSTRUCTOR_ELTS (initial_value);
+
+         if (elts == NULL)
+           {
+             if (pedantic)
+               failure = 3;
+             maxindex = integer_minus_one_node;
+           }
+         else
+           {
+             tree curindex;
+
+             if (TREE_PURPOSE (elts))
+               maxindex = fold_convert (sizetype, TREE_PURPOSE (elts));
+             curindex = maxindex;
+
+             for (elts = TREE_CHAIN (elts); elts; elts = TREE_CHAIN (elts))
+               {
+                 if (TREE_PURPOSE (elts))
+                   curindex = fold_convert (sizetype, TREE_PURPOSE (elts));
+                 else
+                   curindex = size_binop (PLUS_EXPR, curindex, size_one_node);
+
+                 if (tree_int_cst_lt (maxindex, curindex))
+                   maxindex = curindex;
+               }
+           }
+       }
+      else
+       {
+         /* Make an error message unless that happened already.  */
+         if (initial_value != error_mark_node)
+           failure = 1;
+       }
+    }
+  else
+    {
+      failure = 2;
+      if (!do_default)
+       return failure;
+    }
+
+  type = *ptype;
+  elt = TREE_TYPE (type);
+  quals = TYPE_QUALS (strip_array_types (elt));
+  if (quals == 0)
+    unqual_elt = elt;
+  else
+    unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED);
+
+  /* Using build_distinct_type_copy and modifying things afterward instead
+     of using build_array_type to create a new type preserves all of the
+     TYPE_LANG_FLAG_? bits that the front end may have set.  */
+  main_type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
+  TREE_TYPE (main_type) = unqual_elt;
+  TYPE_DOMAIN (main_type) = build_index_type (maxindex);
+  layout_type (main_type);
+
+  if (quals == 0)
+    type = main_type;
+  else
+    type = c_build_qualified_type (main_type, quals);
+
+  *ptype = type;
+  return failure;
+}
 
 #include "gt-c-common.h"
index 63dcb10b40cb09c5293ca214b79bf573adbf85ff..7794adedbeb57ab6e0fb2f48e4be9a32794d2ed4 100644 (file)
@@ -888,6 +888,8 @@ enum lvalue_use {
 
 extern void lvalue_error (enum lvalue_use);
 
+extern int complete_array_type (tree *, tree, bool);
+
 /* In c-gimplify.c  */
 extern void c_genericize (tree);
 extern int c_gimplify_expr (tree *, tree *, tree *);
index 0b86086992e268b7b46f44a8ff9573353847e683..cc45e26c2fd586359880193d1cfd6c2b6981c17d 100644 (file)
@@ -529,7 +529,7 @@ c_finish_incomplete_decl (tree decl)
        {
          warning ("%Jarray %qD assumed to have one element", decl, decl);
 
-         complete_array_type (type, NULL_TREE, 1);
+         complete_array_type (&TREE_TYPE (decl), NULL_TREE, true);
 
          layout_decl (decl, 0);
        }
@@ -3168,14 +3168,15 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
       && TYPE_DOMAIN (type) == 0
       && TREE_CODE (decl) != TYPE_DECL)
     {
-      int do_default
+      bool do_default
        = (TREE_STATIC (decl)
           /* Even if pedantic, an external linkage array
              may have incomplete type at first.  */
           ? pedantic && !TREE_PUBLIC (decl)
           : !DECL_EXTERNAL (decl));
       int failure
-       = complete_array_type (type, DECL_INITIAL (decl), do_default);
+       = complete_array_type (&TREE_TYPE (decl), DECL_INITIAL (decl),
+                              do_default);
 
       /* Get the completed type made by complete_array_type.  */
       type = TREE_TYPE (decl);
@@ -3196,14 +3197,12 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
          else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
            DECL_EXTERNAL (decl) = 1;
        }
-
-      /* TYPE_MAX_VALUE is always one less than the number of elements
-        in the array, because we start counting at zero.  Therefore,
-        warn only if the value is less than zero.  */
-      else if (pedantic && TYPE_DOMAIN (type) != 0
-              && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
+      else if (failure == 3)
        error ("%Jzero or negative size array %qD", decl, decl);
 
+      if (DECL_INITIAL (decl))
+       TREE_TYPE (DECL_INITIAL (decl)) = type;
+
       layout_decl (decl, 0);
     }
 
@@ -3491,17 +3490,19 @@ build_compound_literal (tree type, tree init)
 
   if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
     {
-      int failure = complete_array_type (type, DECL_INITIAL (decl), 1);
-      
+      int failure = complete_array_type (&TREE_TYPE (decl),
+                                        DECL_INITIAL (decl), true);
       gcc_assert (!failure);
+
+      type = TREE_TYPE (decl);
+      TREE_TYPE (DECL_INITIAL (decl)) = type;
     }
 
-  type = TREE_TYPE (decl);
   if (type == error_mark_node || !COMPLETE_TYPE_P (type))
     return error_mark_node;
 
   stmt = build_stmt (DECL_EXPR, decl);
-  complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt);
+  complit = build1 (COMPOUND_LITERAL_EXPR, type, stmt);
   TREE_SIDE_EFFECTS (complit) = 1;
 
   layout_decl (decl, 0);
@@ -3527,73 +3528,6 @@ build_compound_literal (tree type, tree init)
   return complit;
 }
 \f
-/* Make TYPE a complete type based on INITIAL_VALUE.
-   Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
-   2 if there was no information (in which case assume 1 if DO_DEFAULT).  */
-
-int
-complete_array_type (tree type, tree initial_value, int do_default)
-{
-  tree maxindex = NULL_TREE;
-  int value = 0;
-
-  if (initial_value)
-    {
-      /* Note MAXINDEX  is really the maximum index,
-        one less than the size.  */
-      if (TREE_CODE (initial_value) == STRING_CST)
-       {
-         int eltsize
-           = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
-         maxindex = build_int_cst (NULL_TREE,
-                                   (TREE_STRING_LENGTH (initial_value)
-                                    / eltsize) - 1);
-       }
-      else if (TREE_CODE (initial_value) == CONSTRUCTOR)
-       {
-         tree elts = CONSTRUCTOR_ELTS (initial_value);
-         maxindex = build_int_cst (NULL_TREE, -1);
-         for (; elts; elts = TREE_CHAIN (elts))
-           {
-             if (TREE_PURPOSE (elts))
-               maxindex = TREE_PURPOSE (elts);
-             else
-               maxindex = fold (build2 (PLUS_EXPR, integer_type_node,
-                                        maxindex, integer_one_node));
-           }
-       }
-      else
-       {
-         /* Make an error message unless that happened already.  */
-         if (initial_value != error_mark_node)
-           value = 1;
-
-         /* Prevent further error messages.  */
-         maxindex = build_int_cst (NULL_TREE, 0);
-       }
-    }
-
-  if (!maxindex)
-    {
-      if (do_default)
-       maxindex = build_int_cst (NULL_TREE, 0);
-      value = 2;
-    }
-
-  if (maxindex)
-    {
-      TYPE_DOMAIN (type) = build_index_type (maxindex);
-      
-      gcc_assert (TREE_TYPE (maxindex));
-    }
-
-  /* Lay out the type now that we can get the real answer.  */
-
-  layout_type (type);
-
-  return value;
-}
-\f
 /* Determine whether TYPE is a structure with a flexible array member,
    or a union containing such a structure (possibly recursively).  */
 
index bbfed6abbafc20638264ff63993882942adc8837..41b624ec5b777a5b264c88a4c09487f2b5d74eb7 100644 (file)
@@ -378,7 +378,6 @@ extern struct c_declarator *build_array_declarator (tree, struct c_declspecs *,
 extern tree build_enumerator (tree, tree);
 extern void check_for_loop_decls (void);
 extern void mark_forward_parm_decls (void);
-extern int  complete_array_type (tree, tree, int);
 extern void declare_parm_level (void);
 extern void undeclared_variable (tree, location_t);
 extern tree declare_label (tree);
index d7697372ecdfd292b94c367fd370242d120ff22c..859be9d0d39e8cbca6d253620134c0a48e8807d8 100644 (file)
@@ -1,3 +1,10 @@
+2005-03-29  Richard Henderson  <rth@redhat.com>
+
+       PR c/20519
+       * decl.c (cp_complete_array_type): Rename from complete_array_type.
+       Use the new complete_array_type in c-common.c.  Update all callers.
+       * cp-tree.h (cp_complete_array_type): Update to match.
+
 2005-03-24  Geoffrey Keating  <geoffk@apple.com>
 
        * typeck.c (build_static_cast_1): Allow scalar_cast between
index 22e9ee0f8a05fdc7651f5e64e41d4158db3e7d23..ac025d676749b0ff94d4771bf103419ada13c6d2 100644 (file)
@@ -3787,7 +3787,7 @@ extern tree start_decl                            (const cp_declarator *, cp_decl_specifier_seq *, int,
 extern void start_decl_1                       (tree);
 extern void cp_finish_decl                     (tree, tree, tree, int);
 extern void finish_decl                                (tree, tree, tree);
-extern int complete_array_type                 (tree, tree, int);
+extern int cp_complete_array_type              (tree *, tree, bool);
 extern tree build_ptrmemfunc_type              (tree);
 extern tree build_ptrmem_type                   (tree, tree);
 /* the grokdeclarator prototype is in decl.h */
index 1c4568da9d237ad737e0ad665edba60a5f2c418b..eef2cb1744af11051fbedea623d1f5574369faec 100644 (file)
@@ -3913,7 +3913,8 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
         But let's leave it here to ease the eventual merge.  */
       int do_default = !DECL_EXTERNAL (decl);
       tree initializer = init ? init : DECL_INITIAL (decl);
-      int failure = complete_array_type (type, initializer, do_default);
+      int failure = cp_complete_array_type (&TREE_TYPE (decl), initializer,
+                                           do_default);
 
       if (failure == 1)
        error ("initializer fails to determine size of %qD", decl);
@@ -5331,102 +5332,41 @@ expand_static_init (tree decl, tree init)
    3 if the initializer list is empty (in pedantic mode). */
 
 int
-complete_array_type (tree type, tree initial_value, int do_default)
+cp_complete_array_type (tree *ptype, tree initial_value, bool do_default)
 {
-  tree maxindex = NULL_TREE;
-  int value = 0;
+  int failure;
+  tree type, elt_type;
 
   if (initial_value)
     {
       /* An array of character type can be initialized from a
         brace-enclosed string constant.  */
-      if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type)))
+      if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (*ptype)))
          && TREE_CODE (initial_value) == CONSTRUCTOR
          && CONSTRUCTOR_ELTS (initial_value)
          && (TREE_CODE (TREE_VALUE (CONSTRUCTOR_ELTS (initial_value)))
              == STRING_CST)
          && TREE_CHAIN (CONSTRUCTOR_ELTS (initial_value)) == NULL_TREE)
        initial_value = TREE_VALUE (CONSTRUCTOR_ELTS (initial_value));
-
-      /* Note MAXINDEX is really the maximum index, one less than the
-        size.  */
-      if (TREE_CODE (initial_value) == STRING_CST)
-       {
-         int eltsize
-           = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
-         maxindex = build_int_cst (NULL_TREE,
-                                   (TREE_STRING_LENGTH (initial_value)
-                                    / eltsize) - 1);
-       }
-      else if (TREE_CODE (initial_value) == CONSTRUCTOR)
-       {
-         tree elts = CONSTRUCTOR_ELTS (initial_value);
-
-         maxindex = ssize_int (-1);
-         for (; elts; elts = TREE_CHAIN (elts))
-           {
-             if (TREE_PURPOSE (elts))
-               maxindex = TREE_PURPOSE (elts);
-             else
-               maxindex = size_binop (PLUS_EXPR, maxindex, ssize_int (1));
-           }
-
-         if (pedantic && tree_int_cst_equal (maxindex, ssize_int (-1)))
-           value = 3;
-       }
-      else
-       {
-         /* Make an error message unless that happened already.  */
-         if (initial_value != error_mark_node)
-           value = 1;
-         else
-           initial_value = NULL_TREE;
-
-         /* Prevent further error messages.  */
-         maxindex = build_int_cst (NULL_TREE, 0);
-       }
     }
 
-  if (!maxindex)
-    {
-      if (do_default)
-       maxindex = build_int_cst (NULL_TREE, 0);
-      value = 2;
-    }
+  failure = complete_array_type (ptype, initial_value, do_default);
 
-  if (maxindex)
+  /* We can create the array before the element type is complete, which
+     means that we didn't have these two bits set in the original type
+     either.  In completing the type, we are expected to propagate these
+     bits.  See also complete_type which does the same thing for arrays
+     of fixed size.  */
+  type = *ptype;
+  if (TYPE_DOMAIN (type))
     {
-      tree itype;
-      tree domain;
-      tree elt_type;
-
-      domain = build_index_type (maxindex);
-      TYPE_DOMAIN (type) = domain;
-
-      if (initial_value)
-        itype = TREE_TYPE (initial_value);
-      else
-       itype = NULL;
-      if (itype && !TYPE_DOMAIN (itype))
-       TYPE_DOMAIN (itype) = domain;
-      /* The type of the main variant should never be used for arrays
-        of different sizes.  It should only ever be completed with the
-        size of the array.  */
-      if (! TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)))
-       TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = domain;
-
       elt_type = TREE_TYPE (type);
-      TYPE_NEEDS_CONSTRUCTING (type)
-       = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type));
+      TYPE_NEEDS_CONSTRUCTING (type) = TYPE_NEEDS_CONSTRUCTING (elt_type);
       TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
-       = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type));
+       = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (elt_type);
     }
 
-  /* Lay out the type now that we can get the real answer.  */
-
-  layout_type (type);
-
-  return value;
+  return failure;
 }
 \f
 /* Return zero if something is declared to be a member of type
index f0dc8c2f7d616e721945af3bfdb9da5cea0ed017..07f614bedd34fb08408ddb3b056541ac82cd2efe 100644 (file)
@@ -1996,7 +1996,8 @@ finish_compound_literal (tree type, tree initializer_list)
 
         implies that the array has two elements.  */
       if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
-       complete_array_type (type, compound_literal, 1);
+       cp_complete_array_type (&TREE_TYPE (compound_literal),
+                               compound_literal, 1);
     }
 
   return compound_literal;
index 8017af3dd250a95b4f2c7b7fc7a6003cf3d7fb5f..daa23993425d5259fddf73eaadcd0db2206a46f5 100644 (file)
@@ -1123,7 +1123,7 @@ process_init_constructor (tree type, tree init, tree* elts)
 
   result = build_constructor (type, nreverse (members));
   if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
-    complete_array_type (type, result, /*do_default=*/0);
+    cp_complete_array_type (&TREE_TYPE (result), result, /*do_default=*/0);
   if (init)
     TREE_HAS_CONSTRUCTOR (result) = TREE_HAS_CONSTRUCTOR (init);
   if (allconstant)