releasing_vec ctors, indexes;
auto_vec<int> index_pos_hints;
bool activated_union_member_p = false;
+ bool empty_base = false;
while (!refs->is_empty ())
{
if (*valp == NULL_TREE)
no_zero_init = CONSTRUCTOR_NO_CLEARING (*valp);
enum tree_code code = TREE_CODE (type);
- type = refs->pop();
+ tree reftype = refs->pop();
tree index = refs->pop();
if (code == RECORD_TYPE && is_empty_field (index))
fields, which confuses the middle-end. The code below will notice
that we don't have a CONSTRUCTOR for our inner target and just
return init. */
- break;
+ {
+ empty_base = true;
+ break;
+ }
+
+ type = reftype;
if (code == UNION_TYPE && CONSTRUCTOR_NELTS (*valp)
&& CONSTRUCTOR_ELT (*valp, 0)->index != index)
}
}
+ if (*non_constant_p)
+ return t;
+
/* Don't share a CONSTRUCTOR that might be changed later. */
init = unshare_constructor (init);
- if (*valp && TREE_CODE (*valp) == CONSTRUCTOR
- && TREE_CODE (init) == CONSTRUCTOR)
+ gcc_checking_assert (!*valp || (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (*valp), type)));
+ if (empty_base || !(same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (init), type)))
+ {
+ /* For initialization of an empty base, the original target will be
+ *(base*)this, evaluation of which resolves to the object
+ argument, which has the derived type rather than the base type. In
+ this situation, just evaluate the initializer and return, since
+ there's no actual data to store, and we didn't build a CONSTRUCTOR. */
+ empty_base = true;
+ gcc_assert (is_empty_class (TREE_TYPE (init)));
+ if (!*valp)
+ {
+ /* But do make sure we have something in *valp. */
+ *valp = build_constructor (type, nullptr);
+ CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
+ }
+ }
+ else if (*valp && TREE_CODE (*valp) == CONSTRUCTOR
+ && TREE_CODE (init) == CONSTRUCTOR)
{
/* An outer ctx->ctor might be pointing to *valp, so replace
its contents. */
- if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init),
- TREE_TYPE (*valp)))
- {
- /* For initialization of an empty base, the original target will be
- *(base*)this, evaluation of which resolves to the object
- argument, which has the derived type rather than the base type. In
- this situation, just evaluate the initializer and return, since
- there's no actual data to store. */
- gcc_assert (is_empty_class (TREE_TYPE (init)));
- return lval ? target : init;
- }
CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
TREE_CONSTANT (*valp) = TREE_CONSTANT (init);
TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
CONSTRUCTOR_NO_CLEARING (*valp)
= CONSTRUCTOR_NO_CLEARING (init);
}
- else if (TREE_CODE (init) == CONSTRUCTOR
- && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init),
- type))
- {
- /* See above on initialization of empty bases. */
- gcc_assert (is_empty_class (TREE_TYPE (init)) && !lval);
- if (!*valp)
- {
- /* But do make sure we have something in *valp. */
- *valp = build_constructor (type, nullptr);
- CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
- }
- return init;
- }
else
*valp = init;
constructor of a delegating constructor). Leave it up to the
caller that set 'this' to set TREE_READONLY appropriately. */
gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
- (TREE_TYPE (target), type));
+ (TREE_TYPE (target), type) || empty_base);
else
TREE_READONLY (*valp) = true;
}
CONSTRUCTOR_NO_CLEARING (elt) = false;
}
- if (*non_constant_p)
- return t;
- else if (lval)
+ if (lval)
return target;
else
return init;