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.  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.

--
Marek Polacek • Red Hat, Inc. • 300 A St, Boston, MA

Reply via email to