Skip to content

Underlying type of unscoped and unfixed member enumerations of class templates #125180

@thebrandre

Description

@thebrandre

If compatibility with MSVC is enabled, Clang correctly uses int as the underlying type of an unscoped enumeration even if the assigned integer causes an overflow - at least at namespace scope. This is correct in the sense of compatibility, which is officially documented by Microsoft here.

However, if the same declaration appears inside a class template, -fms-compatibility is not honored.

template <typename T>
struct S {
    enum E { X, Y = 0xFFFFFFFF };
};

enum E { X, Y = 0xFFFFFFFF };

constexpr bool check(int) { return true; }
constexpr bool check(unsigned int) { return false; }

static_assert(check(E::X), ""); // succeeds
static_assert(check(S<char>::E::X), ""); // fails

See here on Compiler Explorer: https://godbolt.org/z/Ge8qehE5P

I am aware that there are a lot of open issues on the underlying type of enumerations when using -fms-compatibility (#120759 #122032 #1883 to name a few) but this one should be orthogonal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions