https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117280
Bug ID: 117280 Summary: Accessing a reference member of a volatile-qualified class glvalue is misinterpreted as volatile read Product: gcc Version: 15.0 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- Currently GCC rejects th following example with a seemingly wrong reason. https://godbolt.org/z/v9fKKEaGW ``` struct S { const int& ref; }; constexpr int n = 42; template<class T> constexpr int readref(T&& t) { return static_cast<T&&>(t).ref; } static_assert(::readref(static_cast<volatile S&&>(S{n})) == 42, ""); ``` <source>:9:58: error: non-constant condition for static assertion 9 | static_assert(::readref(static_cast<volatile S&&>(S{n})) == 42, ""); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~ <source>:9:24: error: 'constexpr int readref(T&&) [with T = volatile S]' called in a constant expression 9 | static_assert(::readref(static_cast<volatile S&&>(S{n})) == 42, ""); | ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <source>:5:15: note: 'constexpr int readref(T&&) [with T = volatile S]' is not usable as a 'constexpr' function because: 5 | constexpr int readref(T&& t) { | ^~~~~~~ <source>:6:30: error: lvalue-to-rvalue conversion of a volatile lvalue 't.S::ref' with type 'const int&' 6 | return static_cast<T&&>(t).ref; | ~~~~~~~~~~~~~~~~~~~~^~~ Compiler returned: 1 ~~~~~~~~~~~~~~~~~~~~^~~ It seems that the current standard wording doesn't treat evaluation of a reference member itself as accessing the class object. So perhaps there shouldn't be any volatile read, and this example should be accepted. (A reference non-static data member behaves like it were an "auto-dereferencing" pointer in many cases. But IIUC this example is not such a case.)