This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: Fix crash on invalid use of compound literals


This patch fixes this test case:

+ 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]; 
+ }

We were crashing on the use of the compound literals.

The root problem here was that CONSTRUCTOR nodes are used for several
purposes: compound literals, brace-enclosed initializers, and
pointer-to-member initializers.  The front end wasn't being very clear
about which case was which.

Tested on i686-pc-linux-gnu, applied on the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

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  Mark Mitchell  <mark@codesourcery.com>

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

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.607
diff -c -5 -p -r1.607 class.c
*** cp/class.c	20 Apr 2004 02:52:17 -0000	1.607
--- cp/class.c	22 Apr 2004 21:24:25 -0000
*************** initialize_array (tree decl, tree inits)
*** 6727,6737 ****
    tree context;
  
    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;
  }
  
  /* Build the VTT (virtual table table) for T.
--- 6727,6736 ----
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.962
diff -c -5 -p -r1.962 cp-tree.h
*** cp/cp-tree.h	1 Apr 2004 23:28:08 -0000	1.962
--- cp/cp-tree.h	22 Apr 2004 21:24:26 -0000
*************** struct lang_decl GTY(())
*** 2406,2421 ****
     space from the heap.
  
     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 FIELD_DECL, it means that this field
     has been duly initialized in its constructor.  */
  #define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4 (NODE))
  
  #define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR	   \
  				   && CONSTRUCTOR_ELTS (NODE) == NULL_TREE \
  				   && ! TREE_HAS_CONSTRUCTOR (NODE))
  
--- 2406,2425 ----
     space from the heap.
  
     When appearing in a SAVE_EXPR, it means that underneath
     is a call to a constructor.
  
!    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: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1201
diff -c -5 -p -r1.1201 decl.c
*** cp/decl.c	1 Apr 2004 20:45:00 -0000	1.1201
--- cp/decl.c	22 Apr 2004 21:24:27 -0000
*************** reshape_init (tree type, tree *initp)
*** 4149,4160 ****
  
    /* If the initializer is brace-enclosed, pull initializers from the
       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))
      {
        *initp = TREE_CHAIN (old_init);
        TREE_CHAIN (old_init) = NULL_TREE;
        inits = CONSTRUCTOR_ELTS (old_init_value);
        initp = &inits;
--- 4149,4159 ----
  
    /* If the initializer is brace-enclosed, pull initializers from the
       enclosed elements.  Advance past the brace-enclosed initializer
       now.  */
    if (TREE_CODE (old_init_value) == CONSTRUCTOR
!       && BRACE_ENCLOSED_INITIALIZER_P (old_init_value))
      {
        *initp = TREE_CHAIN (old_init);
        TREE_CHAIN (old_init) = NULL_TREE;
        inits = CONSTRUCTOR_ELTS (old_init_value);
        initp = &inits;
*************** reshape_init (tree type, tree *initp)
*** 4220,4231 ****
        TREE_CHAIN (old_init) = NULL_TREE;
      }
    else
      {
        /* Build a CONSTRUCTOR to hold the contents of the aggregate.  */  
!       new_init = build_constructor (type, NULL_TREE);
!       TREE_HAS_CONSTRUCTOR (new_init) = 1;
  
        if (CLASS_TYPE_P (type))
  	{
  	  tree field;
  
--- 4219,4229 ----
        TREE_CHAIN (old_init) = NULL_TREE;
      }
    else
      {
        /* Build a CONSTRUCTOR to hold the contents of the aggregate.  */  
!       new_init = build_constructor (NULL_TREE, NULL_TREE);
  
        if (CLASS_TYPE_P (type))
  	{
  	  tree field;
  
*************** reshape_init (tree type, tree *initp)
*** 4281,4291 ****
  		    break;
  		  field = next_initializable_field (TREE_CHAIN (field));
  		}
  	    }
  	}
!       else if ((TREE_CODE (type) == ARRAY_TYPE)|| (TREE_CODE (type) == VECTOR_TYPE))
  	{
  	  tree index;
  	  tree max_index;
  
  	  /* If the bound of the array is known, take no more initializers
--- 4279,4290 ----
  		    break;
  		  field = next_initializable_field (TREE_CHAIN (field));
  		}
  	    }
  	}
!       else if (TREE_CODE (type) == ARRAY_TYPE
! 	       || TREE_CODE (type) == VECTOR_TYPE)
  	{
  	  tree index;
  	  tree max_index;
  
  	  /* If the bound of the array is known, take no more initializers
*************** check_initializer (tree decl, tree init,
*** 4397,4407 ****
      }
    else if (!DECL_EXTERNAL (decl) && TREE_CODE (type) == REFERENCE_TYPE)
      init = grok_reference_init (decl, type, init, cleanup);
    else if (init)
      {
!       if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
  	{
  	  /* [dcl.init] paragraph 13,
  	     If T is a scalar type, then a declaration of the form
  	     T x = { a };
  	     is equivalent to
--- 4396,4407 ----
      }
    else if (!DECL_EXTERNAL (decl) && TREE_CODE (type) == REFERENCE_TYPE)
      init = grok_reference_init (decl, type, init, cleanup);
    else if (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
  	     T x = { a };
  	     is equivalent to
*************** check_initializer (tree decl, tree init,
*** 4422,4440 ****
  
        /* If DECL has an array type without a specific bound, deduce the
  	 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))
  	    {
  	      if (TYPE_NON_AGGREGATE_CLASS (type))
  		{
  		  error ("`%D' must be initialized by constructor, not by `{...}'",
  			 decl);
--- 4422,4438 ----
  
        /* If DECL has an array type without a specific bound, deduce the
  	 array size from the initializer.  */
        maybe_deduce_size_from_array_init (decl, init);
        type = TREE_TYPE (decl);
  
        if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))
  	{
  	  if (TREE_CODE (type) == ARRAY_TYPE)
  	    goto initialize_aggr;
  	  else if (TREE_CODE (init) == CONSTRUCTOR
! 		   && BRACE_ENCLOSED_INITIALIZER_P (init))
  	    {
  	      if (TYPE_NON_AGGREGATE_CLASS (type))
  		{
  		  error ("`%D' must be initialized by constructor, not by `{...}'",
  			 decl);
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.367
diff -c -5 -p -r1.367 init.c
*** cp/init.c	16 Apr 2004 16:27:18 -0000	1.367
--- cp/init.c	22 Apr 2004 21:24:27 -0000
*************** perform_member_init (tree member, tree i
*** 338,349 ****
  	{
  	  init = build (INIT_EXPR, type, decl, TREE_VALUE (init));
  	  finish_expr_stmt (init);
  	}
      }
!   else if (TYPE_NEEDS_CONSTRUCTING (type)
! 	   || (init && TYPE_HAS_CONSTRUCTOR (type)))
      {
        if (explicit
  	  && TREE_CODE (type) == ARRAY_TYPE
  	  && init != NULL_TREE
  	  && TREE_CHAIN (init) == NULL_TREE
--- 338,348 ----
  	{
  	  init = build (INIT_EXPR, type, decl, TREE_VALUE (init));
  	  finish_expr_stmt (init);
  	}
      }
!   else if (TYPE_NEEDS_CONSTRUCTING (type))
      {
        if (explicit
  	  && TREE_CODE (type) == ARRAY_TYPE
  	  && init != NULL_TREE
  	  && TREE_CHAIN (init) == NULL_TREE
*************** build_aggr_init (tree exp, tree init, in
*** 1089,1126 ****
    if (init && TREE_CODE (init) != TREE_LIST)
      flags |= LOOKUP_ONLYCONVERTING;
  
    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)
  	{
- 	  /* 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;
  	}
        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);
        stmt_expr = build_vec_init (exp, NULL_TREE, init,
! 				  init && same_type_p (TREE_TYPE (init),
! 						       TREE_TYPE (exp)));
        TREE_READONLY (exp) = was_const;
        TREE_THIS_VOLATILE (exp) = was_volatile;
        TREE_TYPE (exp) = type;
        if (init)
  	TREE_TYPE (init) = itype;
--- 1088,1114 ----
    if (init && TREE_CODE (init) != TREE_LIST)
      flags |= LOOKUP_ONLYCONVERTING;
  
    if (TREE_CODE (type) == ARRAY_TYPE)
      {
!       /* An array may not be initialized use the parenthesized
! 	 initialization form -- unless the initializer is "()".  */
!       if (init && TREE_CODE (init) == TREE_LIST)
  	{
  	  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)
! 	itype = TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
        stmt_expr = build_vec_init (exp, NULL_TREE, init,
! 				  itype && same_type_p (itype,
! 							TREE_TYPE (exp)));
        TREE_READONLY (exp) = was_const;
        TREE_THIS_VOLATILE (exp) = was_volatile;
        TREE_TYPE (exp) = type;
        if (init)
  	TREE_TYPE (init) = itype;
*************** expand_default_init (tree binfo, tree tr
*** 1188,1199 ****
  	/* Do nothing.  We hit this in two cases:  Reference initialization,
  	   where we aren't initializing a real variable, so we don't want
  	   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))
  	{
  	  /* A brace-enclosed initializer for an aggregate.  */
  	  my_friendly_assert (CP_AGGREGATE_TYPE_P (type), 20021016);
  	  init = digest_init (type, init, (tree *)NULL);
  	}
--- 1176,1186 ----
  	/* Do nothing.  We hit this in two cases:  Reference initialization,
  	   where we aren't initializing a real variable, so we don't want
  	   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 (BRACE_ENCLOSED_INITIALIZER_P (init))
  	{
  	  /* A brace-enclosed initializer for an aggregate.  */
  	  my_friendly_assert (CP_AGGREGATE_TYPE_P (type), 20021016);
  	  init = digest_init (type, init, (tree *)NULL);
  	}
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.189
diff -c -5 -p -r1.189 parser.c
*** cp/parser.c	20 Apr 2004 21:50:09 -0000	1.189
--- cp/parser.c	22 Apr 2004 21:24:28 -0000
*************** cp_parser_initializer_clause (cp_parser*
*** 11539,11552 ****
      {
        /* Consume the `{' token.  */
        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))
  	{
  	  /* Parse the initializer list.  */
  	  CONSTRUCTOR_ELTS (initializer)
--- 11539,11548 ----
Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/rtti.c,v
retrieving revision 1.179
diff -c -5 -p -r1.179 rtti.c
*** cp/rtti.c	8 Mar 2004 22:24:35 -0000	1.179
--- cp/rtti.c	22 Apr 2004 21:24:28 -0000
*************** tinfo_base_init (tree desc, tree target)
*** 805,815 ****
    init = tree_cons (NULL_TREE, vtable_ptr, init);
    
    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;
    init = tree_cons (NULL_TREE, init, NULL_TREE);
    
    return init;
  }
  
--- 805,815 ----
    init = tree_cons (NULL_TREE, vtable_ptr, init);
    
    init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
    
    init = build_constructor (NULL_TREE, nreverse (init));
!   TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
    init = tree_cons (NULL_TREE, init, NULL_TREE);
    
    return init;
  }
  
*************** static tree
*** 821,831 ****
  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;
    return init;
  }
  
  /* Return the CONSTRUCTOR expr for a type_info of pointer TYPE.
     DESC provides information about the particular type_info derivation,
--- 821,831 ----
  generic_initializer (tree desc, tree target)
  {
    tree init = tinfo_base_init (desc, target);
    
    init = build_constructor (NULL_TREE, init);
!   TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
    return init;
  }
  
  /* Return the CONSTRUCTOR expr for a type_info of pointer TYPE.
     DESC provides information about the particular type_info derivation,
*************** ptr_initializer (tree desc, tree target,
*** 848,858 ****
    init = tree_cons (NULL_TREE,
                      get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
                      init);
    
    init = build_constructor (NULL_TREE, nreverse (init));
!   TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
    return init;
  }
  
  /* Return the CONSTRUCTOR expr for a type_info of pointer to member data TYPE.
     DESC provides information about the particular type_info derivation,
--- 848,858 ----
    init = tree_cons (NULL_TREE,
                      get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
                      init);
    
    init = build_constructor (NULL_TREE, nreverse (init));
!   TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
    return init;
  }
  
  /* Return the CONSTRUCTOR expr for a type_info of pointer to member data TYPE.
     DESC provides information about the particular type_info derivation,
*************** ptm_initializer (tree desc, tree target,
*** 885,895 ****
    init = tree_cons (NULL_TREE,
  		    get_tinfo_ptr (klass),
  		    init);  
    
    init = build_constructor (NULL_TREE, nreverse (init));
!   TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
    return init;  
  }
  
  /* Check base BINFO to set hint flags in *DATA, which is really an int.
     We use CLASSTYPE_MARKED to tag types we've found as non-virtual bases and
--- 885,895 ----
    init = tree_cons (NULL_TREE,
  		    get_tinfo_ptr (klass),
  		    init);  
    
    init = build_constructor (NULL_TREE, nreverse (init));
!   TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
    return init;  
  }
  
  /* Check base BINFO to set hint flags in *DATA, which is really an int.
     We use CLASSTYPE_MARKED to tag types we've found as non-virtual bases and
*************** class_initializer (tree desc, tree targe
*** 953,963 ****
  {
    tree init = tinfo_base_init (desc, target);
    
    TREE_CHAIN (init) = trail;
    init = build_constructor (NULL_TREE, init);
!   TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
    return init;  
  }
  
  /* Returns true if the typeinfo for type should be placed in
     the runtime library.  */
--- 953,963 ----
  {
    tree init = tinfo_base_init (desc, target);
    
    TREE_CHAIN (init) = trail;
    init = build_constructor (NULL_TREE, init);
!   TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
    return init;  
  }
  
  /* Returns true if the typeinfo for type should be placed in
     the runtime library.  */
*************** get_pseudo_ti_init (tree type, tree var_
*** 1070,1084 ****
                offset = cp_build_binary_op (BIT_IOR_EXPR, offset,
  					   build_int_2 (flags, 0));
                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,
  				  build_int_2 (nbases, 0), base_inits);
  	  /* Prepend the hint flags.  */
--- 1070,1082 ----
Index: cp/typeck2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck2.c,v
retrieving revision 1.156
diff -c -5 -p -r1.156 typeck2.c
*** cp/typeck2.c	1 Apr 2004 20:45:01 -0000	1.156
--- cp/typeck2.c	22 Apr 2004 21:24:28 -0000
*************** tree
*** 486,497 ****
  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.  */
  
    if (tail)
--- 486,495 ----
*************** digest_init (tree type, tree init, tree*
*** 517,530 ****
    
    /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
    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
        && CONSTRUCTOR_ELTS (init) != 0
        && TREE_CHAIN (CONSTRUCTOR_ELTS (init)) == 0)
      {
        element = TREE_VALUE (CONSTRUCTOR_ELTS (init));
        /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
--- 515,525 ----
    
    /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
    if (TREE_CODE (init) == NON_LVALUE_EXPR)
      init = TREE_OPERAND (init, 0);
  
!   if (BRACE_ENCLOSED_INITIALIZER_P (init)
        && CONSTRUCTOR_ELTS (init) != 0
        && TREE_CHAIN (CONSTRUCTOR_ELTS (init)) == 0)
      {
        element = TREE_VALUE (CONSTRUCTOR_ELTS (init));
        /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
*************** digest_init (tree type, tree init, tree*
*** 592,611 ****
    if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
        || code == ENUMERAL_TYPE || code == REFERENCE_TYPE
        || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
        || TYPE_PTR_TO_MEMBER_P (type))
      {
!       if (raw_constructor)
  	{
  	  if (element == 0)
  	    {
  	      error ("initializer for scalar variable requires one element");
  	      return error_mark_node;
  	    }
  	  init = element;
  	}
!       while (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
  	{
  	  pedwarn ("braces around scalar initializer for `%T'", type);
  	  init = CONSTRUCTOR_ELTS (init);
  	  if (TREE_CHAIN (init))
  	    pedwarn ("ignoring extra initializers for `%T'", type);
--- 587,606 ----
    if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
        || code == ENUMERAL_TYPE || code == REFERENCE_TYPE
        || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
        || TYPE_PTR_TO_MEMBER_P (type))
      {
!       if (BRACE_ENCLOSED_INITIALIZER_P (init))
  	{
  	  if (element == 0)
  	    {
  	      error ("initializer for scalar variable requires one element");
  	      return error_mark_node;
  	    }
  	  init = element;
  	}
!       while (BRACE_ENCLOSED_INITIALIZER_P (init))
  	{
  	  pedwarn ("braces around scalar initializer for `%T'", type);
  	  init = CONSTRUCTOR_ELTS (init);
  	  if (TREE_CHAIN (init))
  	    pedwarn ("ignoring extra initializers for `%T'", type);
*************** digest_init (tree type, tree init, tree*
*** 625,643 ****
        return error_mark_node;
      }
  
    if (code == ARRAY_TYPE || code == VECTOR_TYPE || IS_AGGR_TYPE_CODE (code))
      {
!       if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type)
! 	  && TREE_HAS_CONSTRUCTOR (init))
  	{
! 	  error ("subobject of type `%T' must be initialized by constructor, not by `%E'",
! 		    type, init);
! 	  return error_mark_node;
  	}
-       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.  */;
        else if (tail != 0)
  	{
--- 620,639 ----
        return error_mark_node;
      }
  
    if (code == ARRAY_TYPE || code == VECTOR_TYPE || IS_AGGR_TYPE_CODE (code))
      {
!       if (BRACE_ENCLOSED_INITIALIZER_P (init))
  	{
! 	  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 (can_convert_arg (type, TREE_TYPE (init), init)
  	       || TYPE_NON_AGGREGATE_CLASS (type))
  	/* These are never initialized from multiple constructor elements.  */;
        else if (tail != 0)
  	{
*************** process_init_constructor (tree type, tre
*** 875,885 ****
                  }
  	      next1 = digest_init (TREE_TYPE (field), next1, 0);
  
  	      /* Warn when some struct elements are implicitly initialized.  */
  	      if (extra_warnings
! 	          && (!init || TREE_HAS_CONSTRUCTOR (init)))
  		warning ("missing initializer for member `%D'", field);
  	    }
  	  else
  	    {
  	      if (TREE_READONLY (field))
--- 871,881 ----
                  }
  	      next1 = digest_init (TREE_TYPE (field), next1, 0);
  
  	      /* Warn when some struct elements are implicitly initialized.  */
  	      if (extra_warnings
! 	          && (!init || BRACE_ENCLOSED_INITIALIZER_P (init)))
  		warning ("missing initializer for member `%D'", field);
  	    }
  	  else
  	    {
  	      if (TREE_READONLY (field))
*************** process_init_constructor (tree type, tre
*** 891,901 ****
  		error ("member `%D' is uninitialized reference", field);
  
  	      /* Warn when some struct elements are implicitly initialized
  		 to zero.  */
  	      if (extra_warnings
! 	          && (!init || TREE_HAS_CONSTRUCTOR (init)))
  		warning ("missing initializer for member `%D'", field);
  
  	      if (! zero_init_p (TREE_TYPE (field)))
  		next1 = build_zero_init (TREE_TYPE (field),
  					 /*nelts=*/NULL_TREE,
--- 887,897 ----
  		error ("member `%D' is uninitialized reference", field);
  
  	      /* Warn when some struct elements are implicitly initialized
  		 to zero.  */
  	      if (extra_warnings
! 	          && (!init || BRACE_ENCLOSED_INITIALIZER_P (init)))
  		warning ("missing initializer for member `%D'", field);
  
  	      if (! zero_init_p (TREE_TYPE (field)))
  		next1 = build_zero_init (TREE_TYPE (field),
  					 /*nelts=*/NULL_TREE,
Index: testsuite/g++.dg/ext/complit3.C
===================================================================
RCS file: testsuite/g++.dg/ext/complit3.C
diff -N testsuite/g++.dg/ext/complit3.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/ext/complit3.C	22 Apr 2004 21:24:28 -0000
***************
*** 0 ****
--- 1,8 ----
+ // { dg-options "" }
+ 
+ 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]; 
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]