Skip to content

[dcl.enum] Reading non-representable value from enumeration without fixed underlying type via common initial sequence rule. #732

@keinflue

Description

@keinflue

Full name of submitter (unless configured in github; will be published with the issue): Benjamin Sch.

Reference (section label): [dcl.enum], [class.mem.general]

Link to reflector thread (if any):

Issue description:

#include<iostream>
#include<type_traits>

enum E { E0 } e;
enum F { F0, F1, F2, F3 };
static_assert(std::is_same_v<std::underlying_type_t<E>, std::underlying_type_t<F>>);

struct A { E e; };
struct B { F f; };
union U {
    A a;
    B b;
} u;

bool test() {
    return u.a.e == 2;
}

auto ptest = test;

int main() {
    u.b.f = F2;
    std::cout << ptest();
}

Assuming the static_assert passes, then because the two enumerations have the same underlying type, they are layout-compatible and therefore it is permitted to use the inactive u.a.e to read the active u.b.f corresponding to it in the common initial sequence. The read should happen as if u.b.f was nominated, meaning it should read the value 2 even if E is not able to represent that value. And therefore this program must print 1.

Is this intentional? It prevents the implementation from optimizing the body of test to return false; as it otherwise could because E can't represent a value of 2. Is the implementation required to special case this enumeration read through union access?

I originally reported this as bug against Clang in llvm/llvm-project#150833.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions