https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98190
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Ever confirmed|0 |1
Status|RESOLVED |REOPENED
Resolution|DUPLICATE |---
CC| |jakub at gcc dot gnu.org
Last reconfirmed| |2020-12-08
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I don't see UB there, UB would be if you copy a value other than 0 or 1 to the
_Bool variable, but that is not happening here.
Consider even:
static int __attribute__((noipa))
foo (const char *p, const char *q, const int len)
{
for (int i = 0; i < len; p++, q++, i++)
{
int equal;
_Bool x, y;
__builtin_memcpy ((char *) &x, p, sizeof x);
__builtin_memcpy ((char *) &y, q, sizeof y);
equal = (x == y);
if (equal <= 0)
return equal;
}
return 1;
}
int
main ()
{
const _Bool buf[4] = { 1, 0, 0, 0 };
register long x4 asm ("x4") = 0xdeadbeefULL;
register long x5 asm ("x5") = 0xdeadbeefULL;
asm volatile (""::"r" (x4), "r" (x5));
if (foo ((char *) &buf[0], (char *) &buf[0], 1) != 1)
__builtin_abort ();
return 0;
}
Copying through char * from _Bool to _Bool really must work, that is what
happens e.g. in structure assignments etc. if it has _Bool fields.
The reason this is miscompiled is that the aarch64 backend decides that the x
and y variables should be promoted from QImode to SImode and the expansion of
the memcpy folded into assignment sets a MEM_REF with QImode (i.e. low parts of
the promoted DECL_RTL), but nothing sign or zero extends it.