https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116233
Bug ID: 116233 Summary: Explicit specialization of an enum member Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: arthur.j.odwyer at gmail dot com Target Milestone: --- // https://godbolt.org/z/M57PhYx6x template <class> struct Base { enum class E; }; struct X; template<> enum class Base<X>::E { a, b }; ==== GCC complains: <source>:6:41: warning: template specialization of 'enum class Base<X>::E' not allowed by ISO C++ [-Wpedantic] 6 | template<> enum class Base<X>::E { a, b }; | ^ Bug #61491 is directly related. Brian Bi and Sean Baxter and I dug into this on the cpplang Slack: https://cpplang.slack.com/archives/C21PKDHSL/p1722432564976879 We concluded that this is perfectly legal code, so the warning in this case is wrong. ==== However, if you change `enum class` to just `enum`, then the program becomes ill-formed C++ which GCC accepts as an extension, and then the warning becomes correct. We all think the warning in that case is actually *too quiet*, and should be promoted to warn by default. Because right now it allows the following cursed code: // https://godbolt.org/z/Mev9onWaz template <class> struct Base { enum E { a, b, c }; }; struct X; template<> enum Base<X>::E { d, e, f }; int wat[] = { Base<X>::a, // 0 Base<X>::b, // 1 Base<X>::c, // 2 Base<X>::d, // 1 Base<X>::e, // 2 Base<X>::f, // 3 }; Somehow `Base<X>::d` gets the value 1 instead of 0, and `Base<X>::a` etc. remain available even though they shouldn't exist anymore. This is all super weird. And the whole TU is *supposed* to be ill-formed, diagnostic required. So to have it give no error, no warning even with -Wall -Wextra, only a warning with -Wpedantic, is pretty sketchy. To sum up: the existing warning is too quiet (in the unscoped-enum case, where the code is ill-formed according to ISO), and is sometimes wrongly emitted (in the scoped-enum case, where the code is valid according to ISO).