From: Mark Mitchell Date: Thu, 22 Apr 2004 21:29:35 +0000 (+0000) Subject: class.c (initialize_array): Don't set TREE_HAS_CONSTRUCTOR on braced initializer. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=92a62aad855ff49dbd3c975aed87ed141ff447b4;p=gcc.git class.c (initialize_array): Don't set TREE_HAS_CONSTRUCTOR on braced initializer. * 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 42deed34b15..dc6dbcfd271 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,23 @@ +2004-04-22 Mark Mitchell + + * 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 * name-lookup.c (anonymous_namespace_name): Make static. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index c78482c9918..9a9272bf574 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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; } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 262c314051f..8f4465f2322 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b228cd07748..1793fffafec 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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)) { diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 5a64ed51bad..58d9f6db97f 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index fde2f5a0958..0732a650452 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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)) { diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index e9c06160bbe..337c6be94d7 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -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, diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 0a0fdbc0311..b49d4201c50 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -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))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 716435a8460..aa479b4aa23 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-04-22 Mark Mitchell + + * g++.dg/ext/complit3.C: New test. + 2004-04-21 Aldy Hernandez * 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 index 00000000000..56f3d41be64 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit3.C @@ -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]; +}