https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108398
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Siddhesh Poyarekar from comment #3) > Oops, sorry I messed up the reproducer, here's the correct one. The > principles don't really change though: > > unsigned steps[2]; > > int main(void) { > unsigned n_steps = sizeof (steps) / sizeof (unsigned); > > for (unsigned *io = steps; 0 < n_steps; io++) { > if (*io == 0) { > __builtin_printf ("%zu\n", __builtin_dynamic_object_size (io, 0)); > if (__builtin_dynamic_object_size (io, 0) < sizeof (unsigned)) > __builtin_abort (); > n_steps--; > io--; > } > } > > return 0; > } How can this be valid? In the first iteration it already invokes UB, *io == 0, so it will do n_steps-- (why is it misindented?) and then io--, which is invalid, because io == steps and steps - 1 is invalid pointer arithmetics. If you want to do what you do in the body, then better steps[0] should not be 0...