https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115476

--- Comment #7 from Mital Ashok <mital at mitalashok dot co.uk> ---
I think the issue is the same as it was in Clang

The preconditions for `has_unique_object_representations` is
https://eel.is/c++draft/type.traits#tab:meta.unary.prop-row-47-column-3-sentence-1

> T shall be a complete type, cv void, or an array of unknown bound.

Which is implemented in GCC as `check_trait_type (type1, /* kind = */ 1)`
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/cp/semantics.cc;h=08f5f245e7d11a76b975bb04c0075ded1b3ca8ba;hb=609764a42f0cd3f6358562cab98fc220d3d2d9fd#l12969

However, unlike the other traits with the same preconditions (like
`__is_assignable(T, U)` for both of its type arguments), instead of simply
being `false` when given an array with unknown bounds, it recurses in, so it
implicitly has a precondition that "T is cv void or
std::remove_all_extents_t<T> is complete", which should be checked with
`check_trait_type (type1, /* kind = */ 2)`.

`__has_trivial_destructor` also seems to be miscategorized as kind = 1 too,
leading to this unintended result:

    struct Foo;
    static_assert(__has_trivial_destructor(Foo[]));
    struct Foo { ~Foo(); };
    static_assert(!__has_trivial_destructor(Foo[]));

Reply via email to