https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123300
Bug ID: 123300
Summary: Adding [[assume((1<<i) > 0)]] generates an infinite
loop
Product: gcc
Version: 15.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: pieter.p.dev at outlook dot com
Target Milestone: ---
GCC 14 and 15 generate an infinite loop for the following correct code when
compiling with -O2 -DNDEBUG.
https://godbolt.org/z/bh9hcaG19
#include <cstdio>
#include <cassert>
#ifndef NDEBUG
#define INVARIANT(x) assert(x)
#else
#define INVARIANT(x) [[assume(x)]]
#endif
[[gnu::noinline]] void foo(int n, bool do_print) {
for (int i = n; i-- > 0;) {
const int x = 1 << i;
INVARIANT(x > 0);
if (do_print) std::printf("i=%d x=%d\n", i, x);
}
}
int main() {
foo(4, true);
std::puts("Ok");
}
The loop itself is fine, and x=1<<i is valid and positive for all i in [0, 30],
so the assumption is satisfied (as can be verified by removing -DNDEBUG).
Minor changes (such as removing the assumption, changing the loop direction, or
making the printing unconditional) result in the correct code being generated.