class.c (initialize_array): Don't set TREE_HAS_CONSTRUCTOR on braced initializer.
authorMark Mitchell <mark@codesourcery.com>
Thu, 22 Apr 2004 21:29:35 +0000 (21:29 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 22 Apr 2004 21:29:35 +0000 (21:29 +0000)
* class.c (initialize_array): Don't set TREE_HAS_CONSTRUCTOR on
braced initializer.
* cp-tree.h (BRACE_ENCLOSED_INITIALIZER_P): New macro.
* decl.c (reshape_init): Use it.
* init.c (perform_member_init): Remove redundant condition.
(build_aggr_init): Adjust to handle brace-enclosed initializers
correctly.
(expand_default_init): Use BRACE_ENCLOSED_INITIALIZER_P.
* parser.c (cp_parser_initializer_clause): Do not set
TREE_HAS_CONSTRUCTOR on the initializer.
* rtti.c (tinfo_base_init): Likewise.
(generic_initializer): Likewise.
(ptr_initializer): Likewise.
(ptm_initializer): Likewise.
(class_initializer): Likewise.
(get_pseudo_ti_init): Likewise.
* typeck2.c (digest_init): Use BRACE_ENCLOSED_INITIALIZER_P.

* g++.dg/ext/complit3.C: New test.

From-SVN: r81052

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/parser.c
gcc/cp/rtti.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/complit3.C [new file with mode: 0644]

index 42deed34b151acc133d437474993bf2c1a7e4ec2..dc6dbcfd2710a0dbeac2b704c2859fcb8731b5a4 100644 (file)
@@ -1,3 +1,23 @@
+2004-04-22  Mark Mitchell  <mark@codesourcery.com>
+
+       * class.c (initialize_array): Don't set TREE_HAS_CONSTRUCTOR on
+       braced initializer.
+       * cp-tree.h (BRACE_ENCLOSED_INITIALIZER_P): New macro.
+       * decl.c (reshape_init): Use it.
+       * init.c (perform_member_init): Remove redundant condition.
+       (build_aggr_init): Adjust to handle brace-enclosed initializers
+       correctly.
+       (expand_default_init): Use BRACE_ENCLOSED_INITIALIZER_P.
+       * parser.c (cp_parser_initializer_clause): Do not set
+       TREE_HAS_CONSTRUCTOR on the initializer.
+       * rtti.c (tinfo_base_init): Likewise.
+       (generic_initializer): Likewise.
+       (ptr_initializer): Likewise.
+       (ptm_initializer): Likewise.
+       (class_initializer): Likewise.
+       (get_pseudo_ti_init): Likewise.
+       * typeck2.c (digest_init): Use BRACE_ENCLOSED_INITIALIZER_P.
+       
 2004-04-22  Alan Modra  <amodra@bigpond.net.au>
 
        * name-lookup.c (anonymous_namespace_name): Make static.
index c78482c9918d22305c96e663f4ffb320dc9d36b5..9a9272bf57443a55d1d5c7ddb4e56c89e343dcda 100644 (file)
@@ -6729,7 +6729,6 @@ initialize_array (tree decl, tree inits)
   context = DECL_CONTEXT (decl);
   DECL_CONTEXT (decl) = NULL_TREE;
   DECL_INITIAL (decl) = build_constructor (NULL_TREE, inits);
-  TREE_HAS_CONSTRUCTOR (DECL_INITIAL (decl)) = 1;
   cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
   DECL_CONTEXT (decl) = context;
 }
index 262c314051f640076cf5bc33297cdf0754b17d72..8f4465f232243c545e26deefb396da02206611d7 100644 (file)
@@ -2408,13 +2408,17 @@ struct lang_decl GTY(())
    When appearing in a SAVE_EXPR, it means that underneath
    is a call to a constructor.
 
-   When appearing in a CONSTRUCTOR, it means that it was
-   a GNU C constructor expression.
+   When appearing in a CONSTRUCTOR, the expression is a
+   compound literal.
 
    When appearing in a FIELD_DECL, it means that this field
    has been duly initialized in its constructor.  */
 #define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4 (NODE))
 
+/* True if NODE is a brace-enclosed initializer.  */
+#define BRACE_ENCLOSED_INITIALIZER_P(NODE) \
+  (TREE_CODE (NODE) == CONSTRUCTOR && !TREE_TYPE (NODE))
+
 #define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR        \
                                   && CONSTRUCTOR_ELTS (NODE) == NULL_TREE \
                                   && ! TREE_HAS_CONSTRUCTOR (NODE))
index b228cd07748edc36f40d8d7d2580800bb62ee633..1793fffafece089d58ca696c3a729907e01d263a 100644 (file)
@@ -4151,8 +4151,7 @@ reshape_init (tree type, tree *initp)
      enclosed elements.  Advance past the brace-enclosed initializer
      now.  */
   if (TREE_CODE (old_init_value) == CONSTRUCTOR
-      && TREE_TYPE (old_init_value) == NULL_TREE
-      && TREE_HAS_CONSTRUCTOR (old_init_value))
+      && BRACE_ENCLOSED_INITIALIZER_P (old_init_value))
     {
       *initp = TREE_CHAIN (old_init);
       TREE_CHAIN (old_init) = NULL_TREE;
@@ -4222,8 +4221,7 @@ reshape_init (tree type, tree *initp)
   else
     {
       /* Build a CONSTRUCTOR to hold the contents of the aggregate.  */  
-      new_init = build_constructor (type, NULL_TREE);
-      TREE_HAS_CONSTRUCTOR (new_init) = 1;
+      new_init = build_constructor (NULL_TREE, NULL_TREE);
 
       if (CLASS_TYPE_P (type))
        {
@@ -4283,7 +4281,8 @@ reshape_init (tree type, tree *initp)
                }
            }
        }
-      else if ((TREE_CODE (type) == ARRAY_TYPE)|| (TREE_CODE (type) == VECTOR_TYPE))
+      else if (TREE_CODE (type) == ARRAY_TYPE
+              || TREE_CODE (type) == VECTOR_TYPE)
        {
          tree index;
          tree max_index;
@@ -4399,7 +4398,8 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
     init = grok_reference_init (decl, type, init, cleanup);
   else if (init)
     {
-      if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
+      if (TREE_CODE (init) == CONSTRUCTOR 
+         && BRACE_ENCLOSED_INITIALIZER_P (init))
        {
          /* [dcl.init] paragraph 13,
             If T is a scalar type, then a declaration of the form
@@ -4424,15 +4424,13 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
         array size from the initializer.  */
       maybe_deduce_size_from_array_init (decl, init);
       type = TREE_TYPE (decl);
-      if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
-       TREE_TYPE (init) = type;
 
       if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))
        {
          if (TREE_CODE (type) == ARRAY_TYPE)
            goto initialize_aggr;
          else if (TREE_CODE (init) == CONSTRUCTOR
-                  && TREE_HAS_CONSTRUCTOR (init))
+                  && BRACE_ENCLOSED_INITIALIZER_P (init))
            {
              if (TYPE_NON_AGGREGATE_CLASS (type))
                {
index 5a64ed51bada65d00623087763e43ac61414d19e..58d9f6db97f96bb4881a2b0313a79452fd1b3374 100644 (file)
@@ -340,8 +340,7 @@ perform_member_init (tree member, tree init)
          finish_expr_stmt (init);
        }
     }
-  else if (TYPE_NEEDS_CONSTRUCTING (type)
-          || (init && TYPE_HAS_CONSTRUCTOR (type)))
+  else if (TYPE_NEEDS_CONSTRUCTING (type))
     {
       if (explicit
          && TREE_CODE (type) == ARRAY_TYPE
@@ -1091,34 +1090,23 @@ build_aggr_init (tree exp, tree init, int flags)
 
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
-      /* Must arrange to initialize each element of EXP
-        from elements of INIT.  */
-      tree itype = init ? TREE_TYPE (init) : NULL_TREE;
-      
-      if (init && !itype)
+      /* An array may not be initialized use the parenthesized
+        initialization form -- unless the initializer is "()".  */
+      if (init && TREE_CODE (init) == TREE_LIST)
        {
-         /* Handle bad initializers like:
-            class COMPLEX {
-            public:
-              double re, im;
-              COMPLEX(double r = 0.0, double i = 0.0) {re = r; im = i;};
-              ~COMPLEX() {};
-            };
-
-            int main(int argc, char **argv) {
-              COMPLEX zees(1.0, 0.0)[10];
-            }
-         */
          error ("bad array initializer");
          return error_mark_node;
        }
+      /* Must arrange to initialize each element of EXP
+        from elements of INIT.  */
+      tree itype = init ? TREE_TYPE (init) : NULL_TREE;
       if (cp_type_quals (type) != TYPE_UNQUALIFIED)
        TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
       if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED)
-       TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
+       itype = TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
       stmt_expr = build_vec_init (exp, NULL_TREE, init,
-                                 init && same_type_p (TREE_TYPE (init),
-                                                      TREE_TYPE (exp)));
+                                 itype && same_type_p (itype,
+                                                       TREE_TYPE (exp)));
       TREE_READONLY (exp) = was_const;
       TREE_THIS_VOLATILE (exp) = was_volatile;
       TREE_TYPE (exp) = type;
@@ -1190,8 +1178,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags)
           to run a new constructor; and catching an exception, where we
           have already built up the constructor call so we could wrap it
           in an exception region.  */;
-      else if (TREE_CODE (init) == CONSTRUCTOR 
-              && TREE_HAS_CONSTRUCTOR (init))
+      else if (BRACE_ENCLOSED_INITIALIZER_P (init))
        {
          /* A brace-enclosed initializer for an aggregate.  */
          my_friendly_assert (CP_AGGREGATE_TYPE_P (type), 20021016);
index fde2f5a0958f77fd418145b17489b9ab481b089e..0732a650452d0617fc7a457d0c6bfb1e56a9c242 100644 (file)
@@ -11541,10 +11541,6 @@ cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
       cp_lexer_consume_token (parser->lexer);
       /* Create a CONSTRUCTOR to represent the braced-initializer.  */
       initializer = make_node (CONSTRUCTOR);
-      /* Mark it with TREE_HAS_CONSTRUCTOR.  This should not be
-        necessary, but check_initializer depends upon it, for
-        now.  */
-      TREE_HAS_CONSTRUCTOR (initializer) = 1;
       /* If it's not a `}', then there is a non-trivial initializer.  */
       if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
        {
index e9c06160bbe9c410d7f2729fe1c629426e6574e5..337c6be94d758872037e3000b0f3ca11eb8ca508 100644 (file)
@@ -807,7 +807,7 @@ tinfo_base_init (tree desc, tree target)
   init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
   
   init = build_constructor (NULL_TREE, nreverse (init));
-  TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
+  TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
   init = tree_cons (NULL_TREE, init, NULL_TREE);
   
   return init;
@@ -823,7 +823,7 @@ generic_initializer (tree desc, tree target)
   tree init = tinfo_base_init (desc, target);
   
   init = build_constructor (NULL_TREE, init);
-  TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
+  TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
   return init;
 }
 
@@ -850,7 +850,7 @@ ptr_initializer (tree desc, tree target, bool *non_public_ptr)
                     init);
   
   init = build_constructor (NULL_TREE, nreverse (init));
-  TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
+  TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
   return init;
 }
 
@@ -887,7 +887,7 @@ ptm_initializer (tree desc, tree target, bool *non_public_ptr)
                    init);  
   
   init = build_constructor (NULL_TREE, nreverse (init));
-  TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
+  TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
   return init;  
 }
 
@@ -955,7 +955,7 @@ class_initializer (tree desc, tree target, tree trail)
   
   TREE_CHAIN (init) = trail;
   init = build_constructor (NULL_TREE, init);
-  TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
+  TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
   return init;  
 }
 
@@ -1072,11 +1072,9 @@ get_pseudo_ti_init (tree type, tree var_desc, bool *non_public_p)
               base_init = tree_cons (NULL_TREE, offset, base_init);
               base_init = tree_cons (NULL_TREE, tinfo, base_init);
               base_init = build_constructor (NULL_TREE, base_init);
-             TREE_HAS_CONSTRUCTOR (base_init) = 1;
               base_inits = tree_cons (NULL_TREE, base_init, base_inits);
             }
          base_inits = build_constructor (NULL_TREE, base_inits);
-         TREE_HAS_CONSTRUCTOR (base_inits) = 1;
          base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
          /* Prepend the number of bases.  */
          base_inits = tree_cons (NULL_TREE,
index 0a0fdbc03112ef9141e202c20c35e8fb8f5879f0..b49d4201c50a35cd3a6e7dc86c40b9df15f362f9 100644 (file)
@@ -488,8 +488,6 @@ digest_init (tree type, tree init, tree* tail)
   enum tree_code code = TREE_CODE (type);
   tree element = NULL_TREE;
   tree old_tail_contents = NULL_TREE;
-  /* Nonzero if INIT is a braced grouping.  */
-  int raw_constructor;
 
   /* By default, assume we use one element from a list.
      We correct this later in the sole case where it is not true.  */
@@ -519,10 +517,7 @@ digest_init (tree type, tree init, tree* tail)
   if (TREE_CODE (init) == NON_LVALUE_EXPR)
     init = TREE_OPERAND (init, 0);
 
-  raw_constructor = (TREE_CODE (init) == CONSTRUCTOR 
-                    && TREE_HAS_CONSTRUCTOR (init));
-
-  if (raw_constructor
+  if (BRACE_ENCLOSED_INITIALIZER_P (init)
       && CONSTRUCTOR_ELTS (init) != 0
       && TREE_CHAIN (CONSTRUCTOR_ELTS (init)) == 0)
     {
@@ -594,7 +589,7 @@ digest_init (tree type, tree init, tree* tail)
       || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
       || TYPE_PTR_TO_MEMBER_P (type))
     {
-      if (raw_constructor)
+      if (BRACE_ENCLOSED_INITIALIZER_P (init))
        {
          if (element == 0)
            {
@@ -603,7 +598,7 @@ digest_init (tree type, tree init, tree* tail)
            }
          init = element;
        }
-      while (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
+      while (BRACE_ENCLOSED_INITIALIZER_P (init))
        {
          pedwarn ("braces around scalar initializer for `%T'", type);
          init = CONSTRUCTOR_ELTS (init);
@@ -627,15 +622,16 @@ digest_init (tree type, tree init, tree* tail)
 
   if (code == ARRAY_TYPE || code == VECTOR_TYPE || IS_AGGR_TYPE_CODE (code))
     {
-      if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type)
-         && TREE_HAS_CONSTRUCTOR (init))
+      if (BRACE_ENCLOSED_INITIALIZER_P (init))
        {
-         error ("subobject of type `%T' must be initialized by constructor, not by `%E'",
-                   type, init);
-         return error_mark_node;
+         if (TYPE_NON_AGGREGATE_CLASS (type))
+           {
+             error ("subobject of type `%T' must be initialized by constructor, not by `%E'",
+                    type, init);
+             return error_mark_node;
+           }
+         return process_init_constructor (type, init, (tree *)0);
        }
-      else if (raw_constructor)
-       return process_init_constructor (type, init, (tree *)0);
       else if (can_convert_arg (type, TREE_TYPE (init), init)
               || TYPE_NON_AGGREGATE_CLASS (type))
        /* These are never initialized from multiple constructor elements.  */;
@@ -877,7 +873,7 @@ process_init_constructor (tree type, tree init, tree* elts)
 
              /* Warn when some struct elements are implicitly initialized.  */
              if (extra_warnings
-                 && (!init || TREE_HAS_CONSTRUCTOR (init)))
+                 && (!init || BRACE_ENCLOSED_INITIALIZER_P (init)))
                warning ("missing initializer for member `%D'", field);
            }
          else
@@ -893,7 +889,7 @@ process_init_constructor (tree type, tree init, tree* elts)
              /* Warn when some struct elements are implicitly initialized
                 to zero.  */
              if (extra_warnings
-                 && (!init || TREE_HAS_CONSTRUCTOR (init)))
+                 && (!init || BRACE_ENCLOSED_INITIALIZER_P (init)))
                warning ("missing initializer for member `%D'", field);
 
              if (! zero_init_p (TREE_TYPE (field)))
index 716435a84607c622cb8dcf67117a775a0941497a..aa479b4aa23707f152e7e32966c56f51652d613f 100644 (file)
@@ -1,3 +1,7 @@
+2004-04-22  Mark Mitchell  <mark@codesourcery.com>
+
+       * g++.dg/ext/complit3.C: New test.
+
 2004-04-21  Aldy Hernandez  <aldyh@redhat.com>
 
        * gcc.dg/altivec-1.c: XFAIL for powerpc-eabispe.
diff --git a/gcc/testsuite/g++.dg/ext/complit3.C b/gcc/testsuite/g++.dg/ext/complit3.C
new file mode 100644 (file)
index 0000000..56f3d41
--- /dev/null
@@ -0,0 +1,6 @@
+int Compound_Literals_0()
+{
+  static int y[] = (int []) {1, 2, 3}; // { dg-error "" }
+  static int z[] = (int [3]) {1}; // { dg-error "" }
+  return y[0]+z[0]; 
+}