https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938
--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Martin Sebor from comment #4)
> Yes, the problem is that triviality isn't sufficient to decide whether the
> transformation can be enabled. I think we need to check whether the type
> has a trivial default ctor. Maybe like this:
>
> --- gcc/cp/decl.c (revision 272482)
> +++ gcc/cp/decl.c (working copy)
> @@ -5853,7 +5853,7 @@ reshape_init_array_1 (tree elt_type, tree max_inde
> break;
> }
>
> - if (sized_array_p && trivial_type_p (elt_type))
> + if (sized_array_p && type_has_nontrivial_default_init (elt_type))
Is that backwards? That checks whether it has a non-trivial default ctor.
But I think that's still wrong, as comment 3 shows, the transformation can go
from calling a non-trivial ctor to something completely different. If the type
has any user-defined constructors then you can't assume that a zero initializer
is default init.
Also, the testcase from PR 90947 is miscompiled with an array of pointers,
which are definitely trivial and don't have a non-trivial default ctor.
#include <assert.h>
#include <stdio.h>
static const char *vector_swizzle(int vecsize, int index)
{
static const char *swizzle[4][4] = {
{ ".x", ".y", ".z", ".w" },
{ ".xy", ".yz", ".zw", nullptr },
{ ".xyz", ".yzw", nullptr, nullptr },
{ "", nullptr, nullptr, nullptr },
};
assert(vecsize >= 1 && vecsize <= 4);
assert(index >= 0 && index < 4);
assert(swizzle[vecsize - 1][index]);
return swizzle[vecsize - 1][index];
}
int main()
{
puts(vector_swizzle(4, 0));
}