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).
  • [Bug c++/116233] New: Explic... arthur.j.odwyer at gmail dot com via Gcc-bugs

Reply via email to