typeck2.c (process_init_constructor): If there are elements that don't have initializers and they need to have...
* typeck2.c (process_init_constructor): If there are elements that don't have initializers and they need to have constructors run, supply them with initializers. Fixes Sec12/6_1/P12176.C. * class.c (finish_struct_1): A class with a 0-width bitfield is still empty. Fixes Sec9/6/R09387.r0. Really this time. From-SVN: r23819
This commit is contained in:
parent
d0b9a143e7
commit
e626754922
|
@ -1,3 +1,12 @@
|
||||||
|
1998-11-23 Jason Merrill <jason@yorick.cygnus.com>
|
||||||
|
|
||||||
|
* typeck2.c (process_init_constructor): If there are elements
|
||||||
|
that don't have initializers and they need to have constructors
|
||||||
|
run, supply them with initializers.
|
||||||
|
|
||||||
|
* class.c (finish_struct_1): A class with a 0-width bitfield is
|
||||||
|
still empty.
|
||||||
|
|
||||||
1998-11-23 Mark Mitchell <mark@markmitchell.com>
|
1998-11-23 Mark Mitchell <mark@markmitchell.com>
|
||||||
|
|
||||||
* pt.c (instantiate_class_template): Don't try to figure out what
|
* pt.c (instantiate_class_template): Don't try to figure out what
|
||||||
|
|
|
@ -1235,7 +1235,9 @@ add_method (type, fields, method)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DECL_CONV_FN_P (method))
|
if (TREE_VEC_ELT (method_vec, i))
|
||||||
|
/* We found a match. */;
|
||||||
|
else if (DECL_CONV_FN_P (method))
|
||||||
{
|
{
|
||||||
/* Type conversion operators have to come before
|
/* Type conversion operators have to come before
|
||||||
ordinary methods; add_conversions depends on this to
|
ordinary methods; add_conversions depends on this to
|
||||||
|
@ -3453,6 +3455,10 @@ finish_struct_1 (t, warn_anon)
|
||||||
if (TREE_CODE (x) == FIELD_DECL)
|
if (TREE_CODE (x) == FIELD_DECL)
|
||||||
{
|
{
|
||||||
DECL_PACKED (x) |= TYPE_PACKED (t);
|
DECL_PACKED (x) |= TYPE_PACKED (t);
|
||||||
|
|
||||||
|
if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
|
||||||
|
/* A zero-width bitfield doesn't do the trick. */;
|
||||||
|
else
|
||||||
empty = 0;
|
empty = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
125
gcc/cp/typeck2.c
125
gcc/cp/typeck2.c
|
@ -703,6 +703,9 @@ digest_init (type, init, 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);
|
||||||
|
|
||||||
|
if (TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == type)
|
||||||
|
return init;
|
||||||
|
|
||||||
raw_constructor = TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == 0;
|
raw_constructor = TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == 0;
|
||||||
|
|
||||||
if (raw_constructor
|
if (raw_constructor
|
||||||
|
@ -873,6 +876,7 @@ process_init_constructor (type, init, elts)
|
||||||
/* List of the elements of the result constructor,
|
/* List of the elements of the result constructor,
|
||||||
in reverse order. */
|
in reverse order. */
|
||||||
register tree members = NULL;
|
register tree members = NULL;
|
||||||
|
register tree next1;
|
||||||
tree result;
|
tree result;
|
||||||
int allconstant = 1;
|
int allconstant = 1;
|
||||||
int allsimple = 1;
|
int allsimple = 1;
|
||||||
|
@ -907,10 +911,10 @@ process_init_constructor (type, init, elts)
|
||||||
else
|
else
|
||||||
len = -1; /* Take as many as there are */
|
len = -1; /* Take as many as there are */
|
||||||
|
|
||||||
for (i = 0; (len < 0 || i < len) && tail != 0; i++)
|
for (i = 0; len < 0 || i < len; i++)
|
||||||
|
{
|
||||||
|
if (tail)
|
||||||
{
|
{
|
||||||
register tree next1;
|
|
||||||
|
|
||||||
if (TREE_PURPOSE (tail)
|
if (TREE_PURPOSE (tail)
|
||||||
&& (TREE_CODE (TREE_PURPOSE (tail)) != INTEGER_CST
|
&& (TREE_CODE (TREE_PURPOSE (tail)) != INTEGER_CST
|
||||||
|| TREE_INT_CST_LOW (TREE_PURPOSE (tail)) != i))
|
|| TREE_INT_CST_LOW (TREE_PURPOSE (tail)) != i))
|
||||||
|
@ -921,13 +925,9 @@ process_init_constructor (type, init, elts)
|
||||||
tree tail1 = tail;
|
tree tail1 = tail;
|
||||||
next1 = digest_init (TREE_TYPE (type),
|
next1 = digest_init (TREE_TYPE (type),
|
||||||
TREE_VALUE (tail), &tail1);
|
TREE_VALUE (tail), &tail1);
|
||||||
if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type))
|
my_friendly_assert (TYPE_MAIN_VARIANT (TREE_TYPE (type))
|
||||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (type)) != TYPE_MAIN_VARIANT (TREE_TYPE (next1)))
|
== TYPE_MAIN_VARIANT (TREE_TYPE (next1)),
|
||||||
{
|
981123);
|
||||||
/* The fact this needs to be done suggests this code needs
|
|
||||||
to be totally rewritten. */
|
|
||||||
next1 = convert_for_initialization (NULL_TREE, TREE_TYPE (type), next1, LOOKUP_NORMAL, "initialization", NULL_TREE, 0);
|
|
||||||
}
|
|
||||||
my_friendly_assert (tail1 == 0
|
my_friendly_assert (tail1 == 0
|
||||||
|| TREE_CODE (tail1) == TREE_LIST, 319);
|
|| TREE_CODE (tail1) == TREE_LIST, 319);
|
||||||
if (tail == tail1 && len < 0)
|
if (tail == tail1 && len < 0)
|
||||||
|
@ -943,6 +943,27 @@ process_init_constructor (type, init, elts)
|
||||||
next1 = error_mark_node;
|
next1 = error_mark_node;
|
||||||
tail = TREE_CHAIN (tail);
|
tail = TREE_CHAIN (tail);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (len < 0)
|
||||||
|
/* We're done. */
|
||||||
|
break;
|
||||||
|
else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type)))
|
||||||
|
{
|
||||||
|
/* If this type needs constructors run for
|
||||||
|
default-initialization, we can't rely on the backend to do it
|
||||||
|
for us, so build up TARGET_EXPRs. If the type in question is
|
||||||
|
a class, just build one up; if it's an array, recurse. */
|
||||||
|
|
||||||
|
if (IS_AGGR_TYPE (TREE_TYPE (type)))
|
||||||
|
next1 = build_functional_cast (TREE_TYPE (type), NULL_TREE);
|
||||||
|
else
|
||||||
|
next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
|
||||||
|
next1 = digest_init (TREE_TYPE (type), next1, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* The default zero-initialization is fine for us; don't
|
||||||
|
add anything to the CONSTRUCTOR. */
|
||||||
|
break;
|
||||||
|
|
||||||
if (next1 == error_mark_node)
|
if (next1 == error_mark_node)
|
||||||
erroneous = 1;
|
erroneous = 1;
|
||||||
|
@ -978,11 +999,9 @@ process_init_constructor (type, init, elts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (field = TYPE_FIELDS (type); field && tail;
|
for (field = TYPE_FIELDS (type); field;
|
||||||
field = TREE_CHAIN (field))
|
field = TREE_CHAIN (field))
|
||||||
{
|
{
|
||||||
register tree next1;
|
|
||||||
|
|
||||||
if (! DECL_NAME (field) && DECL_C_BIT_FIELD (field))
|
if (! DECL_NAME (field) && DECL_C_BIT_FIELD (field))
|
||||||
{
|
{
|
||||||
members = expr_tree_cons (field, integer_zero_node, members);
|
members = expr_tree_cons (field, integer_zero_node, members);
|
||||||
|
@ -992,6 +1011,8 @@ process_init_constructor (type, init, elts)
|
||||||
if (TREE_CODE (field) != FIELD_DECL)
|
if (TREE_CODE (field) != FIELD_DECL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (tail)
|
||||||
|
{
|
||||||
if (TREE_PURPOSE (tail)
|
if (TREE_PURPOSE (tail)
|
||||||
&& TREE_PURPOSE (tail) != field
|
&& TREE_PURPOSE (tail) != field
|
||||||
&& TREE_PURPOSE (tail) != DECL_NAME (field))
|
&& TREE_PURPOSE (tail) != DECL_NAME (field))
|
||||||
|
@ -1012,6 +1033,46 @@ process_init_constructor (type, init, elts)
|
||||||
next1 = error_mark_node;
|
next1 = error_mark_node;
|
||||||
tail = TREE_CHAIN (tail);
|
tail = TREE_CHAIN (tail);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
|
||||||
|
{
|
||||||
|
/* If this type needs constructors run for
|
||||||
|
default-initialization, we can't rely on the backend to do it
|
||||||
|
for us, so build up TARGET_EXPRs. If the type in question is
|
||||||
|
a class, just build one up; if it's an array, recurse. */
|
||||||
|
|
||||||
|
if (IS_AGGR_TYPE (TREE_TYPE (field)))
|
||||||
|
next1 = build_functional_cast (TREE_TYPE (field),
|
||||||
|
NULL_TREE);
|
||||||
|
else
|
||||||
|
next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE,
|
||||||
|
NULL_TREE);
|
||||||
|
next1 = digest_init (TREE_TYPE (field), next1, 0);
|
||||||
|
|
||||||
|
/* Warn when some struct elements are implicitly initialized. */
|
||||||
|
if (extra_warnings)
|
||||||
|
cp_warning ("missing initializer for member `%D'", field);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (TREE_READONLY (field))
|
||||||
|
cp_error ("uninitialized const member `%D'", field);
|
||||||
|
else if (TYPE_LANG_SPECIFIC (TREE_TYPE (field))
|
||||||
|
&& CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field)))
|
||||||
|
cp_error ("member `%D' with uninitialized const fields",
|
||||||
|
field);
|
||||||
|
else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
|
||||||
|
cp_error ("member `%D' is uninitialized reference", field);
|
||||||
|
|
||||||
|
/* Warn when some struct elements are implicitly initialized
|
||||||
|
to zero. */
|
||||||
|
if (extra_warnings)
|
||||||
|
cp_warning ("missing initializer for member `%D'", field);
|
||||||
|
|
||||||
|
/* The default zero-initialization is fine for us; don't
|
||||||
|
add anything to the CONSTRUCTOR. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (next1 == error_mark_node)
|
if (next1 == error_mark_node)
|
||||||
erroneous = 1;
|
erroneous = 1;
|
||||||
|
@ -1021,44 +1082,10 @@ process_init_constructor (type, init, elts)
|
||||||
allsimple = 0;
|
allsimple = 0;
|
||||||
members = expr_tree_cons (field, next1, members);
|
members = expr_tree_cons (field, next1, members);
|
||||||
}
|
}
|
||||||
for (; field; field = TREE_CHAIN (field))
|
|
||||||
{
|
|
||||||
if (TREE_CODE (field) != FIELD_DECL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Does this field have a default initialization? */
|
|
||||||
if (DECL_INITIAL (field))
|
|
||||||
{
|
|
||||||
register tree next1 = DECL_INITIAL (field);
|
|
||||||
if (TREE_CODE (next1) == ERROR_MARK)
|
|
||||||
erroneous = 1;
|
|
||||||
else if (!TREE_CONSTANT (next1))
|
|
||||||
allconstant = 0;
|
|
||||||
else if (! initializer_constant_valid_p (next1, TREE_TYPE (next1)))
|
|
||||||
allsimple = 0;
|
|
||||||
members = expr_tree_cons (field, next1, members);
|
|
||||||
}
|
|
||||||
else if (TREE_READONLY (field))
|
|
||||||
error ("uninitialized const member `%s'",
|
|
||||||
IDENTIFIER_POINTER (DECL_NAME (field)));
|
|
||||||
else if (TYPE_LANG_SPECIFIC (TREE_TYPE (field))
|
|
||||||
&& CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field)))
|
|
||||||
error ("member `%s' with uninitialized const fields",
|
|
||||||
IDENTIFIER_POINTER (DECL_NAME (field)));
|
|
||||||
else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
|
|
||||||
error ("member `%s' is uninitialized reference",
|
|
||||||
IDENTIFIER_POINTER (DECL_NAME (field)));
|
|
||||||
/* Warn when some struct elements are implicitly initialized
|
|
||||||
to zero. */
|
|
||||||
else if (extra_warnings)
|
|
||||||
warning ("missing initializer for member `%s'",
|
|
||||||
IDENTIFIER_POINTER (DECL_NAME (field)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (TREE_CODE (type) == UNION_TYPE)
|
else if (TREE_CODE (type) == UNION_TYPE)
|
||||||
{
|
{
|
||||||
register tree field = TYPE_FIELDS (type);
|
register tree field = TYPE_FIELDS (type);
|
||||||
register tree next1;
|
|
||||||
|
|
||||||
/* Find the first named field. ANSI decided in September 1990
|
/* Find the first named field. ANSI decided in September 1990
|
||||||
that only named fields count here. */
|
that only named fields count here. */
|
||||||
|
@ -1087,8 +1114,8 @@ process_init_constructor (type, init, elts)
|
||||||
if (temp)
|
if (temp)
|
||||||
field = temp, win = 1;
|
field = temp, win = 1;
|
||||||
else
|
else
|
||||||
error ("no field `%s' in union being initialized",
|
cp_error ("no field `%D' in union being initialized",
|
||||||
IDENTIFIER_POINTER (TREE_PURPOSE (tail)));
|
TREE_PURPOSE (tail));
|
||||||
}
|
}
|
||||||
if (!win)
|
if (!win)
|
||||||
TREE_VALUE (tail) = error_mark_node;
|
TREE_VALUE (tail) = error_mark_node;
|
||||||
|
|
Loading…
Reference in New Issue