On Wed, 4 Nov 2020 at 10:46, Stephan Bergmann via Libstdc++ <libstd...@gcc.gnu.org> wrote: > To me it looks like it boils down to disagreement between g++ and > clang++ over > > > struct S { static constexpr int f() { return 0; } }; > > void f(S & s) { static_assert(s.f(), ""); } > > where I think Clang might be right in rejecting it based on [expr.const] > "An expression e is a core constant expression unless [...] an > id-expression that refers to a variable or data member of reference type > unless the reference has a preceding initialization [...]"
There's more to it than that. It's a disagreement over [expr.ref]/1. For a static member call, gcc just plain doesn't evaluate the s in s.f(). But [expr.ref]/1 says it's evaluated, and since it's not a constant expression, clang rejects it, and gcc accepts it. That's why your fix works; it removes the use of the otherwise-mostly-ignored object expression for a call to a static member function. So, I think gcc is accepting-invalid here, and we should just apply the fix you suggested.