&& TREE_CODE (new_obj) == COMPONENT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (new_obj, 0))) == UNION_TYPE)
{
+ tree ctor = build_constructor (TREE_TYPE (new_obj), NULL);
+ CONSTRUCTOR_NO_CLEARING (ctor) = true;
tree activate = build2 (INIT_EXPR, TREE_TYPE (new_obj),
- new_obj,
- build_constructor (TREE_TYPE (new_obj),
- NULL));
+ new_obj, ctor);
cxx_eval_constant_expression (ctx, activate,
lval, non_constant_p, overflow_p,
jump_target);
}
/* If there's no explicit init for this field, it's value-initialized. */
+
+ if (AGGREGATE_TYPE_P (TREE_TYPE (t)))
+ {
+ /* As in cxx_eval_store_expression, insert an empty CONSTRUCTOR
+ and copy the flags. */
+ constructor_elt *e = get_or_insert_ctor_field (whole, part);
+ e->value = value = build_constructor (TREE_TYPE (part), NULL);
+ CONSTRUCTOR_ZERO_PADDING_BITS (value)
+ = CONSTRUCTOR_ZERO_PADDING_BITS (whole);
+ return value;
+ }
+
value = build_value_init (TREE_TYPE (t), tf_warning_or_error);
return cxx_eval_constant_expression (ctx, value,
lval,
--- /dev/null
+// PR c++/120577
+// { dg-do compile { target c++20 } }
+
+template <class _Tp> struct optional {
+ union {
+ _Tp __val_;
+ };
+ template <class... _Args>
+ constexpr optional(_Args... __args)
+ : __val_(__args...) {}
+};
+template <class _Tp, class... _Args>
+constexpr optional<_Tp> make_optional(_Args... __args) {
+ return optional<_Tp>(__args...);
+}
+
+struct __non_trivial_if {
+ constexpr __non_trivial_if() {}
+};
+struct allocator : __non_trivial_if {};
+struct __padding {};
+struct __short {
+ [[__no_unique_address__]] __padding __padding_;
+ int __data_;
+};
+struct basic_string {
+ union {
+ __short __s;
+ };
+ [[__no_unique_address__]] allocator __alloc_;
+ constexpr basic_string(int, int) {}
+};
+auto opt = make_optional<basic_string>(4, 'X');