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[]));