https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112296
Bug ID: 112296 Summary: __builtin_constant_p doesn't propagate through member functions Product: gcc Version: 13.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: barry.revzin at gmail dot com Target Milestone: --- Here's a short example: using size_t = decltype(sizeof(0)); struct Span { int const* ptr; size_t len; inline constexpr auto size() const noexcept -> size_t { return len; } }; inline int direct(Span span) { return __builtin_constant_p(span.size()); } inline int indirect(Span span) { size_t s = span.size(); return __builtin_constant_p(s); } int call_direct(int const* p) { return direct({.ptr=p, .len=8}); } int call_indirect(int const* p) { return indirect({.ptr=p, .len=8}); } The functions direct() and indirect() do the same thing - try to see if span's size is constant, with direct checking size() directly and indirect first caching it to a local variable and checking that variable. In both cases, the size is constant - but on -O3 call_direct() returns 0 while call_indirect() returns 1. That is, __builtin_constant_p tells me the size is constant - but only if I put it into a variable first. Checking __builtin_constant_p(span.len) also returns 1, but in the real code the member variable is private and my only access to it is via the size() function.