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));
}

Reply via email to