[Bug middle-end/85563] [8/9 regression] -Wmaybe-uninitialized false alarm regression with __builtin_unreachable and GCC 8
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Feb 1 14:09:00 GMT 2019
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85563
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Before doing manual reduction, I've tried:
struct S { void *a, *b; int c; };
static inline int foo (void *p)
{
return ((unsigned) ((__INTPTR_TYPE__) p) & 7) == 3;
}
static inline void *bar (void *p)
{
struct S *s = (struct S *) ((__INTPTR_TYPE__) p & ~(__INTPTR_TYPE__) 7);
return s->a;
}
static inline void *baz (void *p)
{
struct S *s = (struct S *) ((__INTPTR_TYPE__) p & ~(__INTPTR_TYPE__) 7);
return s->b;
}
static inline int quux (void *p)
{
struct S *s = (struct S *) ((__INTPTR_TYPE__) p & ~(__INTPTR_TYPE__) 7);
return s->c;
}
void *v;
void *
qux (void)
{
foo (v) ? 0 : __builtin_unreachable ();
void *q;
for (void *p = v; foo (p) && (q = bar (p)); p = baz (p))
if (quux (q))
break;
return q;
}
but that one doesn't warn for some reason, anyway, the visible change is that
the __builtin_unreachable () is removed during vrp1 only on the #c6 testcase,
and there is really no spot to actually record what the assertion asserted.
Vframe_list.0_1 = Vframe_list;
a.1_11 = (long int) Vframe_list.0_1;
# RANGE [3, 4294967291]
_9 = (unsigned int) a.1_11;
# RANGE [3, 3] NONZERO 3
_8 = _9 & 7;
if (_8 != 3)
goto <bb 3>; [0.00%]
else
goto <bb 7>; [100.00%]
<bb 7> [local count: 118111600]:
goto <bb 4>; [100.00%]
<bb 3> [count: 0]:
__builtin_unreachable ();
before vrp1, while the [3, 3] range for _8 is useful, that SSA_NAME is
immediately removed as nothing uses it. And the [3, 4294967291] range is both
not really useful and _9 isn't used by anything either. In the range info,
while we record a non-zero mask, we don't have a zero mask, so there is no way
to express that (whatever & 7) == 3 (let alone == 6 or similar). Plus we don't
record any ranges for pointers, just NULL vs. non-NULL. So, in the end the
__builtin_unreachable () here is totally useless.
The only hope is that if it is kept (e.g. with the rationale that the only
SSA_NAMEs where something could be recorded are single use and after the
__builtin_unreachable () removal they will have zero uses and removed), then we
decide to peel off the first iteration or tests from it and thus merge that
with the __builtin_unreachable ().
Or just rewrite whatever you are doing to something that doesn't suffer from
this. Say:
(tail) = Vframe_list;
while ((frame1 = XCAR (tail), 1))
{
body...;
tail = XCDR (tail);
if (!CONSP (tail))
break;
}
More information about the Gcc-bugs
mailing list