Commit 92a62aad by Mark Mitchell Committed by Mark Mitchell

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
parent 838a4849
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> 2004-04-22 Alan Modra <amodra@bigpond.net.au>
* name-lookup.c (anonymous_namespace_name): Make static. * name-lookup.c (anonymous_namespace_name): Make static.
......
...@@ -6729,7 +6729,6 @@ initialize_array (tree decl, tree inits) ...@@ -6729,7 +6729,6 @@ initialize_array (tree decl, tree inits)
context = DECL_CONTEXT (decl); context = DECL_CONTEXT (decl);
DECL_CONTEXT (decl) = NULL_TREE; DECL_CONTEXT (decl) = NULL_TREE;
DECL_INITIAL (decl) = build_constructor (NULL_TREE, inits); 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); cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
DECL_CONTEXT (decl) = context; DECL_CONTEXT (decl) = context;
} }
......
...@@ -2408,13 +2408,17 @@ struct lang_decl GTY(()) ...@@ -2408,13 +2408,17 @@ struct lang_decl GTY(())
When appearing in a SAVE_EXPR, it means that underneath When appearing in a SAVE_EXPR, it means that underneath
is a call to a constructor. is a call to a constructor.
When appearing in a CONSTRUCTOR, it means that it was When appearing in a CONSTRUCTOR, the expression is a
a GNU C constructor expression. compound literal.
When appearing in a FIELD_DECL, it means that this field When appearing in a FIELD_DECL, it means that this field
has been duly initialized in its constructor. */ has been duly initialized in its constructor. */
#define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4 (NODE)) #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 \ #define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \
&& CONSTRUCTOR_ELTS (NODE) == NULL_TREE \ && CONSTRUCTOR_ELTS (NODE) == NULL_TREE \
&& ! TREE_HAS_CONSTRUCTOR (NODE)) && ! TREE_HAS_CONSTRUCTOR (NODE))
......
...@@ -4151,8 +4151,7 @@ reshape_init (tree type, tree *initp) ...@@ -4151,8 +4151,7 @@ reshape_init (tree type, tree *initp)
enclosed elements. Advance past the brace-enclosed initializer enclosed elements. Advance past the brace-enclosed initializer
now. */ now. */
if (TREE_CODE (old_init_value) == CONSTRUCTOR if (TREE_CODE (old_init_value) == CONSTRUCTOR
&& TREE_TYPE (old_init_value) == NULL_TREE && BRACE_ENCLOSED_INITIALIZER_P (old_init_value))
&& TREE_HAS_CONSTRUCTOR (old_init_value))
{ {
*initp = TREE_CHAIN (old_init); *initp = TREE_CHAIN (old_init);
TREE_CHAIN (old_init) = NULL_TREE; TREE_CHAIN (old_init) = NULL_TREE;
...@@ -4222,8 +4221,7 @@ reshape_init (tree type, tree *initp) ...@@ -4222,8 +4221,7 @@ reshape_init (tree type, tree *initp)
else else
{ {
/* Build a CONSTRUCTOR to hold the contents of the aggregate. */ /* Build a CONSTRUCTOR to hold the contents of the aggregate. */
new_init = build_constructor (type, NULL_TREE); new_init = build_constructor (NULL_TREE, NULL_TREE);
TREE_HAS_CONSTRUCTOR (new_init) = 1;
if (CLASS_TYPE_P (type)) if (CLASS_TYPE_P (type))
{ {
...@@ -4283,7 +4281,8 @@ reshape_init (tree type, tree *initp) ...@@ -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 index;
tree max_index; tree max_index;
...@@ -4399,7 +4398,8 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) ...@@ -4399,7 +4398,8 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
init = grok_reference_init (decl, type, init, cleanup); init = grok_reference_init (decl, type, init, cleanup);
else if (init) 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, /* [dcl.init] paragraph 13,
If T is a scalar type, then a declaration of the form 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) ...@@ -4424,15 +4424,13 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
array size from the initializer. */ array size from the initializer. */
maybe_deduce_size_from_array_init (decl, init); maybe_deduce_size_from_array_init (decl, init);
type = TREE_TYPE (decl); 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 (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))
{ {
if (TREE_CODE (type) == ARRAY_TYPE) if (TREE_CODE (type) == ARRAY_TYPE)
goto initialize_aggr; goto initialize_aggr;
else if (TREE_CODE (init) == CONSTRUCTOR else if (TREE_CODE (init) == CONSTRUCTOR
&& TREE_HAS_CONSTRUCTOR (init)) && BRACE_ENCLOSED_INITIALIZER_P (init))
{ {
if (TYPE_NON_AGGREGATE_CLASS (type)) if (TYPE_NON_AGGREGATE_CLASS (type))
{ {
......
...@@ -340,8 +340,7 @@ perform_member_init (tree member, tree init) ...@@ -340,8 +340,7 @@ perform_member_init (tree member, tree init)
finish_expr_stmt (init); finish_expr_stmt (init);
} }
} }
else if (TYPE_NEEDS_CONSTRUCTING (type) else if (TYPE_NEEDS_CONSTRUCTING (type))
|| (init && TYPE_HAS_CONSTRUCTOR (type)))
{ {
if (explicit if (explicit
&& TREE_CODE (type) == ARRAY_TYPE && TREE_CODE (type) == ARRAY_TYPE
...@@ -1091,34 +1090,23 @@ build_aggr_init (tree exp, tree init, int flags) ...@@ -1091,34 +1090,23 @@ build_aggr_init (tree exp, tree init, int flags)
if (TREE_CODE (type) == ARRAY_TYPE) if (TREE_CODE (type) == ARRAY_TYPE)
{ {
/* Must arrange to initialize each element of EXP /* An array may not be initialized use the parenthesized
from elements of INIT. */ initialization form -- unless the initializer is "()". */
tree itype = init ? TREE_TYPE (init) : NULL_TREE; if (init && TREE_CODE (init) == TREE_LIST)
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"); error ("bad array initializer");
return error_mark_node; 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) if (cp_type_quals (type) != TYPE_UNQUALIFIED)
TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type); TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED) 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, stmt_expr = build_vec_init (exp, NULL_TREE, init,
init && same_type_p (TREE_TYPE (init), itype && same_type_p (itype,
TREE_TYPE (exp))); TREE_TYPE (exp)));
TREE_READONLY (exp) = was_const; TREE_READONLY (exp) = was_const;
TREE_THIS_VOLATILE (exp) = was_volatile; TREE_THIS_VOLATILE (exp) = was_volatile;
TREE_TYPE (exp) = type; TREE_TYPE (exp) = type;
...@@ -1190,8 +1178,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags) ...@@ -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 to run a new constructor; and catching an exception, where we
have already built up the constructor call so we could wrap it have already built up the constructor call so we could wrap it
in an exception region. */; in an exception region. */;
else if (TREE_CODE (init) == CONSTRUCTOR else if (BRACE_ENCLOSED_INITIALIZER_P (init))
&& TREE_HAS_CONSTRUCTOR (init))
{ {
/* A brace-enclosed initializer for an aggregate. */ /* A brace-enclosed initializer for an aggregate. */
my_friendly_assert (CP_AGGREGATE_TYPE_P (type), 20021016); my_friendly_assert (CP_AGGREGATE_TYPE_P (type), 20021016);
......
...@@ -11541,10 +11541,6 @@ cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p) ...@@ -11541,10 +11541,6 @@ cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
/* Create a CONSTRUCTOR to represent the braced-initializer. */ /* Create a CONSTRUCTOR to represent the braced-initializer. */
initializer = make_node (CONSTRUCTOR); 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 it's not a `}', then there is a non-trivial initializer. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE)) if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
{ {
......
...@@ -807,7 +807,7 @@ tinfo_base_init (tree desc, tree target) ...@@ -807,7 +807,7 @@ tinfo_base_init (tree desc, tree target)
init = tree_cons (NULL_TREE, decay_conversion (name_decl), init); init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
init = build_constructor (NULL_TREE, nreverse (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); init = tree_cons (NULL_TREE, init, NULL_TREE);
return init; return init;
...@@ -823,7 +823,7 @@ generic_initializer (tree desc, tree target) ...@@ -823,7 +823,7 @@ generic_initializer (tree desc, tree target)
tree init = tinfo_base_init (desc, target); tree init = tinfo_base_init (desc, target);
init = build_constructor (NULL_TREE, init); 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; return init;
} }
...@@ -850,7 +850,7 @@ ptr_initializer (tree desc, tree target, bool *non_public_ptr) ...@@ -850,7 +850,7 @@ ptr_initializer (tree desc, tree target, bool *non_public_ptr)
init); init);
init = build_constructor (NULL_TREE, nreverse (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; return init;
} }
...@@ -887,7 +887,7 @@ ptm_initializer (tree desc, tree target, bool *non_public_ptr) ...@@ -887,7 +887,7 @@ ptm_initializer (tree desc, tree target, bool *non_public_ptr)
init); init);
init = build_constructor (NULL_TREE, nreverse (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; return init;
} }
...@@ -955,7 +955,7 @@ class_initializer (tree desc, tree target, tree trail) ...@@ -955,7 +955,7 @@ class_initializer (tree desc, tree target, tree trail)
TREE_CHAIN (init) = trail; TREE_CHAIN (init) = trail;
init = build_constructor (NULL_TREE, init); 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; return init;
} }
...@@ -1072,11 +1072,9 @@ get_pseudo_ti_init (tree type, tree var_desc, bool *non_public_p) ...@@ -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, offset, base_init);
base_init = tree_cons (NULL_TREE, tinfo, base_init); base_init = tree_cons (NULL_TREE, tinfo, base_init);
base_init = build_constructor (NULL_TREE, 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 = tree_cons (NULL_TREE, base_init, base_inits);
} }
base_inits = build_constructor (NULL_TREE, 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); base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
/* Prepend the number of bases. */ /* Prepend the number of bases. */
base_inits = tree_cons (NULL_TREE, base_inits = tree_cons (NULL_TREE,
......
...@@ -488,8 +488,6 @@ digest_init (tree type, tree init, tree* tail) ...@@ -488,8 +488,6 @@ digest_init (tree type, tree init, tree* tail)
enum tree_code code = TREE_CODE (type); enum tree_code code = TREE_CODE (type);
tree element = NULL_TREE; tree element = NULL_TREE;
tree old_tail_contents = 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. /* By default, assume we use one element from a list.
We correct this later in the sole case where it is not true. */ 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) ...@@ -519,10 +517,7 @@ digest_init (tree type, tree init, tree* tail)
if (TREE_CODE (init) == NON_LVALUE_EXPR) if (TREE_CODE (init) == NON_LVALUE_EXPR)
init = TREE_OPERAND (init, 0); init = TREE_OPERAND (init, 0);
raw_constructor = (TREE_CODE (init) == CONSTRUCTOR if (BRACE_ENCLOSED_INITIALIZER_P (init)
&& TREE_HAS_CONSTRUCTOR (init));
if (raw_constructor
&& CONSTRUCTOR_ELTS (init) != 0 && CONSTRUCTOR_ELTS (init) != 0
&& TREE_CHAIN (CONSTRUCTOR_ELTS (init)) == 0) && TREE_CHAIN (CONSTRUCTOR_ELTS (init)) == 0)
{ {
...@@ -594,7 +589,7 @@ digest_init (tree type, tree init, tree* tail) ...@@ -594,7 +589,7 @@ digest_init (tree type, tree init, tree* tail)
|| code == BOOLEAN_TYPE || code == COMPLEX_TYPE || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
|| TYPE_PTR_TO_MEMBER_P (type)) || TYPE_PTR_TO_MEMBER_P (type))
{ {
if (raw_constructor) if (BRACE_ENCLOSED_INITIALIZER_P (init))
{ {
if (element == 0) if (element == 0)
{ {
...@@ -603,7 +598,7 @@ digest_init (tree type, tree init, tree* tail) ...@@ -603,7 +598,7 @@ digest_init (tree type, tree init, tree* tail)
} }
init = element; 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); pedwarn ("braces around scalar initializer for `%T'", type);
init = CONSTRUCTOR_ELTS (init); init = CONSTRUCTOR_ELTS (init);
...@@ -627,15 +622,16 @@ digest_init (tree type, tree init, tree* tail) ...@@ -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 (code == ARRAY_TYPE || code == VECTOR_TYPE || IS_AGGR_TYPE_CODE (code))
{ {
if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type) if (BRACE_ENCLOSED_INITIALIZER_P (init))
&& TREE_HAS_CONSTRUCTOR (init))
{ {
error ("subobject of type `%T' must be initialized by constructor, not by `%E'", if (TYPE_NON_AGGREGATE_CLASS (type))
type, init); {
return error_mark_node; 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) else if (can_convert_arg (type, TREE_TYPE (init), init)
|| TYPE_NON_AGGREGATE_CLASS (type)) || TYPE_NON_AGGREGATE_CLASS (type))
/* These are never initialized from multiple constructor elements. */; /* These are never initialized from multiple constructor elements. */;
...@@ -877,7 +873,7 @@ process_init_constructor (tree type, tree init, tree* elts) ...@@ -877,7 +873,7 @@ process_init_constructor (tree type, tree init, tree* elts)
/* Warn when some struct elements are implicitly initialized. */ /* Warn when some struct elements are implicitly initialized. */
if (extra_warnings if (extra_warnings
&& (!init || TREE_HAS_CONSTRUCTOR (init))) && (!init || BRACE_ENCLOSED_INITIALIZER_P (init)))
warning ("missing initializer for member `%D'", field); warning ("missing initializer for member `%D'", field);
} }
else else
...@@ -893,7 +889,7 @@ process_init_constructor (tree type, tree init, tree* elts) ...@@ -893,7 +889,7 @@ process_init_constructor (tree type, tree init, tree* elts)
/* Warn when some struct elements are implicitly initialized /* Warn when some struct elements are implicitly initialized
to zero. */ to zero. */
if (extra_warnings if (extra_warnings
&& (!init || TREE_HAS_CONSTRUCTOR (init))) && (!init || BRACE_ENCLOSED_INITIALIZER_P (init)))
warning ("missing initializer for member `%D'", field); warning ("missing initializer for member `%D'", field);
if (! zero_init_p (TREE_TYPE (field))) if (! zero_init_p (TREE_TYPE (field)))
......
2004-04-22 Mark Mitchell <mark@codesourcery.com>
* g++.dg/ext/complit3.C: New test.
2004-04-21 Aldy Hernandez <aldyh@redhat.com> 2004-04-21 Aldy Hernandez <aldyh@redhat.com>
* gcc.dg/altivec-1.c: XFAIL for powerpc-eabispe. * gcc.dg/altivec-1.c: XFAIL for powerpc-eabispe.
......
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];
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment