https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71224
Bug ID: 71224 Summary: Looping over local copy of aggregate invokes undefined behavior -Waggressive-loop-optimizations Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: ibuclaw at gdcproject dot org Target Milestone: --- This probably is related to PR71177 and PR57199, but unlike them, this test case doesn't have any external header dependencies, and also affects gcc as well as g++. However though it was in my D frontend that I first noticed this problem. --- typedef __SIZE_TYPE__ size_t; typedef struct Array { size_t length; size_t* ptr; } Array; void setlength(Array* pthis, size_t nlength) { Array aggr = { .length=pthis->length - nlength, .ptr=pthis->ptr + nlength }; for (size_t key = 0; key < aggr.length; key++) aggr.ptr[key] = 1; } void insertBack(Array* pthis) { setlength(pthis, pthis->length + 1); } --- Can even reproduce if I were to lower the loop in the same way that g++ does. --- void setlength(Array* pthis, size_t nlength) { Array aggr = {.length=pthis->length - nlength, .ptr=pthis->ptr + nlength}; size_t key = 0; while (1) { if (aggr.length <= key) break; aggr.ptr[key] = 1; key++; } } --- Just like in PR57199, if I were to add the following inside the for body. --- if (__builtin_expect(aggr.length > key, 0)) __builtin_unreachable(); --- Then the warning goes away.