This code: void fun() { constexpr int x = 42; constexpr struct { decltype(x) x; constexpr auto operator()(int a) const { return a * x; } } f = {x}; static_assert(f(0) == 0); static_assert(f(2) == 2*42); } (trying to show how a compiler might expand a lambda [x](int a){return a*x;}), fails to compile on all GCCs I tested, incl. trunk as installed on godbold, with the following incomprehensible error message: 6 : <source>:6:21: error: declaration of 'const int fun()::<unnamed struct>::x' [-fpermissive] decltype(x) x; ^ 3 : <source>:3:19: error: changes meaning of 'x' from 'constexpr const int x' [-fpermissive] constexpr int x = 42; ^ Clang 4 and MSVC 2017 both compile this code just fine: https://godbolt.org/g/4L6ULo The problem is not the constexpr. I only added those to be able to execute the function call operator without having to run the executable.
Why do you think this is a bug in GCC? The "changes meaning of" is a diagnostic which is not required by C++. That is the C++ language says this is invalid code but a diagnostic is not required.
Basically: because the other two compilers compile it.
(In reply to Marc Mutz from comment #2) > Basically: because the other two compilers compile it. Again so ...
[basic.scope.class] p2: "A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule." So the code is ill-formed, no diagnostic required. GCC is allowed to reject it. The other compilers fail to diagnose it (which is also conforming).
*** Bug 108587 has been marked as a duplicate of this bug. ***
Just a quick note p1787 (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html) moves around the place where it says no diagnostic is required but the effect is the same. it is now in [class.member.lookup]/7 (note in the draft C++23 standard it is /6). But GCC is still doing a valid diagnostic because of this. That is the standard didn't change in this area, just changed where the wording was.