https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117912
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- That is completely unreadable. Slightly cleaned up: long s; struct A *foo (void); struct B {}; struct B bar (struct B *); void baz (void) __attribute__((__error__ ("baz"))); struct A { int a; struct B b; char c[]; }; void qux (void) { struct A *p = foo (); bar (&p->b); unsigned long q = __builtin_object_size (p->c, 1); if (q < s) baz (); } I think the error started with r0-118806-g17742d62a2438144b6235. The early_objsz pass doesn't do anything special here, because it sees it is used on a flexible array member (and even char c[24]; wouldn't do anything, as it is still considered flexible-like array member, only having some other field after that would cause MIN_EXPR <__builtin_object_size (p->c, 1), 24>. But then fre1 comes and changes _1 = &p_8->b; bar (_1); - _2 = &p_8->c; - q_10 = __builtin_object_size (_2, 1); + q_10 = __builtin_object_size (_1, 1); (i.e. value numbers &p_8->b and &p_8->c the same, p->b is zero sized structure, so &p->b == &p->c and for GIMPLE most pointer conversions are useless). Similar testcase could be struct S { int a; int b[2]; int c; }; struct T { int a; int b[24]; int c; }; union U { struct S s; struct T t; }; void bar (int *); void baz (union U *); __SIZE_TYPE__ foo (union U *p) { bar (&p->s.b[0]); baz (p); /* Assume this changes current member from p->s to p->t. */ return __builtin_object_size (&p->t.b[0], 1); } although SCCVN doesn't value number &p->t.b[0] the same as &p->s.b[0] for some reason. The only fix I have in mind right now is simply treat __bos and __bdos 1 and 3 modes as 0 and 2 during late objsz. Though it surely will lead to some regressions in security coverage, e.g. if early inlining doesn't figure out what field (or fields) certain pointer points to (or could point to) and it is only late inlining that allows us to see it. Or a targetted fix just for this case, if during late objsz we see __bos/__bdos 1 or 3 on zero sized field and there is a non-zero sized one or flexible array member or flexible-like array member at the same address, conservatively assume the larger.