On 12/3/19 12:49 PM, Marek Polacek wrote:
On Tue, Dec 03, 2019 at 02:07:02AM -0500, Jason Merrill wrote:
On 12/2/19 5:09 PM, Marek Polacek wrote:
On Mon, Dec 02, 2019 at 12:09:17PM -0500, Jason Merrill wrote:
On 12/1/19 8:09 PM, Marek Polacek wrote:
+ || (skip_empty
+ && is_really_empty_class (TREE_TYPE (field),
This should probably check DECL_SIZE (field) == size_zero_node instead,
since that will properly distinguish between overlapping and non-overlapping
data members of empty class type. And please test how this works with data
members of empty class type both with and without [[no_unique_address]].
I don't think that's possible -- empty classes in C++ have sizeof(char), unless
their only member is char[0], then their DECL_SIZE is 0.
I think you're talking about the TYPE_SIZE of the class, and I'm talking
about the DECL_SIZE of the FIELD_DECL.
I'm really looking at the DECL_SIZE:
Breakpoint 5, next_initializable_field (field=<field_decl 0x7fffea90dc78 s>,
skip_empty=true)
at /home/mpolacek/src/gcc/gcc/cp/decl.c:5928
5928 && is_really_empty_class (TREE_TYPE (field),
(gdb) p field
$1 = <field_decl 0x7fffea90dc78 s>
(gdb) p DECL_SIZE($1)
$2 = <integer_cst 0x7fffea8e0f60>
(gdb) pge
8
This is constexpr-init8.C:
struct S {
constexpr S(int) {}
};
struct W {
constexpr W(int) : s(8), p() {}
S s;
int *p;
};
constexpr auto a = W(42);
I think that's because layout_class_type has:
6491 else if (might_overlap && is_empty_class (type))
6492 layout_empty_base_or_field (rli, field, empty_base_offsets);
6493 else
6494 layout_nonempty_base_or_field (rli, field, NULL_TREE,
6495 empty_base_offsets);
and here might_overlap is false because 's' doesn't have [[no_unique_address]].
So we emit the FIELD_DECL with size 8.
Yes, that's correct. So I don't think we want to skip 's' in
next_initializable_field; it should have a normal initializer.
Its type CLASSTYPE_SIZE is 0 though.
I don't know but I'd rather not mess with this...
I've added two testcases: constexpr-init13.C and constexpr-init14.C. Is there
another scenario regarding [[no_unique_address]] that you want me to test?
I think the classes with empty base fields need to have another initialized
field after them to have a chance of tripping
if (idx != field)
And sure enough, that's exactly the case for
struct E {
constexpr E() = default;
constexpr E(int) {}
};
struct S {
E e;
int i;
constexpr S() : e{} , i(11) { }
};
constexpr S s;
And that's even without [[no_unique_address]].
So it's a valid concern. It's unclear to me how this should be resolved.
What does the initializer for s look like in this case?
Jason