Skip to content

"case value is not a constant expression" casting an enum to an integer #168247

@berolinux

Description

@berolinux

This code (extracted from systemtap 5.4) builds fine with g++ 15.2, but errors out with clang++ 21.1.5:

enum a {
        b
};

const a c = (a) -1;

int main(int argc, char **argv) {
        int d;
        switch(d) {
        case c:
                break;
        }
}

clang's complaint is

test.cpp:10:7: error: case value is not a constant expression
   10 |         case c:
      |              ^
test.cpp:10:7: note: initializer of 'c' is not a constant expression
test.cpp:5:9: note: declared here
    5 | const a c = (a) -1;
      |         ^
1 error generated.

Not 100% sure which compiler is doing the right thing here; the problem persists if I change const a c = (a) -1; to constexpr a c = (a) -1; (gcc still compiles it without even throwing a warning about it, even with -Wall -Wextra).

Both compilers are set up to use -std=c++20.

Making it even more obvious with constexpr a c = static_cast<a>(static_cast<unsigned>(-1)); results in another situation where gcc and clang disagree:

clang:

test.cpp:5:13: error: constexpr variable 'c' must be initialized by a constant expression
    5 | constexpr a c = static_cast<a>(static_cast<unsigned>(-1));
      |             ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:5:17: note: integer value 4294967295 is outside the valid range of values [0, 1] for the enumeration type 'a'
    5 | constexpr a c = static_cast<a>(static_cast<unsigned>(-1));
      |                 ^
test.cpp:10:7: error: case value is not a constant expression
   10 |         case c:
      |              ^
test.cpp:10:7: note: initializer of 'c' is not a constant expression
test.cpp:5:13: note: declared here
    5 | constexpr a c = static_cast<a>(static_cast<unsigned>(-1));
      |             ^
2 errors generated.

gcc still compiles it without complaining about anything.
Again not sure what the standard says about this, clang's error certainly looks reasonable in this case (but I'd think gcc is right in the constexpr a c = (a) -1; case).

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"constexprAnything related to constant evaluationcwg-issueAn issue that was filed to the Core Working Groupdiverges-from:gccDoes the clang frontend diverge from gcc on this issueinvalidResolved as invalid, i.e. not a bugundefined behaviour

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions