<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/126792>126792</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [Clang++] Reference to inactive union member is not produce error in the constexpr context
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          safocl
      </td>
    </tr>
</table>

<pre>
    I believe the code here produces undefined behavior, but in the context of a contextual expression the compiler does not issue a compilation error.
https://godbolt.org/z/758Knbs8a
```cpp
consteval int foo2(){
    union uu{int i; short ui;} u;
    // u.i = 11;
    int& i_ref = u.i;

    u.i = 11;

    return i_ref;
}

int main(){
  return foo2();
}
```

[\[class.union.general\]](https://eel.is/c++draft/class.union.general)

> A union is a class defined with the class-key union.

> In a union, a non-static data member is active if its name refers to an object whose lifetime has begun and has not ended ([basic.life]). At most one of the non-static data members of an object of union type can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time.

[\[basic.memobj#intro.object-1.sentence-2\]](https://eel.is/c++draft/basic.memobj#intro.object-1.sentence-2)
> The constructs in a C++ program create, destroy, refer to, access, and manipulate objects. An object is created [...] when implicitly changing the active member of a union [...]

[\[class.union#general-3.sentence-2\]](https://eel.is/c++draft/class.union#general-3.sentence-2)
> Each non-static data member is allocated as if it were the sole member of a non-union class.

[\[basic.life#2.sentence-3\]](https://eel.is/c++draft/basic.life#2.sentence-3)
> except that if the object is a union member or subobject thereof, its lifetime only begins if that union member is the initialized member in the union ([dcl.init.aggr], [class.base.init]), or as described in [class.union], [class.copy.ctor], and [class.copy.assign], and except as described in [allocator.members].

[\[class.union#general-5.3\]](https://eel.is/c++draft/class.union#general-5.3)
> 5 When the left operand of an assignment operator involves a member
> access expression ([expr.ref]) that nominates a union member, it may
> begin the lifetime of that union member, as described below. For an
> expression E, define the set S(E) of subexpressions of E as follows:
> [...]
> (5.3) -- Otherwise, S(E) is empty.

and
https://eel.is/c++draft/class.union#general-example-2
_(that is, the members of the union do not become active (lifetime does not start for any of them) if the union is not declared with initialization, or when explicit or implicit initialization of one of its members has not occurred.)_

[\[dcl.ref#6.sentence-6\]](https://eel.is/c++draft/dcl.ref#6.sentence-6)
> The behavior of an evaluation of a reference ([expr.prim.id], [expr.ref]) that does not happen after ([intro.races]) the initialization of the reference is undefined.

And only follow behavior is defined:

[\[basic.life#10.sentence-1\]](https://eel.is/c++draft/basic.life#10.sentence-1)
> After the lifetime of an object has ended and before the storage which
> the object occupied is reused or released, if a new object is created
> at the storage location which the original object occupied and the original
> object was transparently replaceable by the new object, a pointer that
> pointed to the original object, a reference that referred to the original
> object, or the name of the original object will automatically refer to
> the new object and, once the lifetime of the new object has started,
> can be used to manipulate the new object.

[\[basic.life#8\]](https://eel.is/c++draft/basic.life#8)
> 8 Similarly, before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any glvalue that refers to the original object may be used but only in limited ways. For an object under construction or destruction, see [class.cdtor]. Otherwise, such a glvalue refers to allocated storage ([basic.stc.dynamic.allocation]), and using the properties of the glvalue that do not depend on its value is well-defined. The program has undefined behavior if
> (8.1) -- the glvalue is used to access the object, or

[\[expr.post#expr.ref-2.sentence-1\]](https://eel.is/c++draft/expr.post#expr.ref-2.sentence-1)
> For the first option (dot), [...] if the id-expression names a non-static data member, the first expression shall be a glvalue.

[\[https://eel.is/c++draft/dcl.ref#example-3\]](https://eel.is/c++draft/dcl.ref#example-3)
> [Example 3: 
```cpp
int &f(int&);
int &g();
extern int &ir3;
int *ip = 0;
int &ir1 = *ip;                 // undefined behavior: null pointer
int &ir2 = f(ir3);              // undefined behavior: ir3 not yet initialized
int &ir3 = g();
int &ir4 = f(ir4);              // undefined behavior: ir4 used in its own initializer

char x alignas(int);
int &ir5 = *reinterpret_cast<int *>(&x);    // undefined behavior: initializer refers to char object
```
> — end example]

(_// undefined behavior: ir3 not yet initialized_)

_(that is, there are no exceptions to the fact that the reference must be initialized to a valid object. But it is initialized by a member of a union whose lifetime has not started.)_
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJysWctu4zrSfhpmU7BgU3ZiL7KwcwEO_sUPzBlglgFFlW2eoUiBpOL4PP2gSOpix-npdE-jgVgiWazLV18VKeG9OhjER7basdXznejC0bpHL_ZW6rvK1ufHP6BCrfAdIRwRpK0RjugQWmfrTqKHztS4VwZrqPAo3pV1jD9B1QVQJq8xAT8C2D2I_qETGvCjdei9sv20plUaHdQWPRgbQHnfYVxDIyLQTHTOuoLNt8cQWs_KLeOvjL8ebF1ZHQrrDoy__s3468Nq_X-m8mvB5lt2P0__Zduy-VZa4wO-Cw3KBNhbyxlfM75hDzs23wIAdIb26jr2sKMpipU78EfrAnT0mz08Q0d_0-ykAnSFAlY-w2IxDikTGL8H9eZwHwe7QqXRfqerRfm1w9A5k9blgYfnNEwKNUKZS53zgokx01W9_UlCDPYTW-2kFt4X0djigAad0HHgmf7z9aWLEXWhPOOvkvEd47vaiX2gxxtC-CbvVL7ANntTeQolTYYeMCcVjin29Hr2bzynuUVemv_8YUCkAUKWAGPNzAcRlIRaBAENNhW6uIEM6h1B7UEFD0Y0CA736DwEC8KArf5CGeB0tB5Bqz0G1SAchYcKD50BYer4ROhDU2MN5MzVrhJeyYIWRM9sCtgGaKwPYA0SsMmI22r5iPtha7vP7gjnFkEKAxX2aosAwpyBdCJDw1FQDqSfCO9Cd3Ev8fNbZ_k-WIc15WP243Sr4goUydYGG1v9xXipTHC2SNrPFoVHE9BInPHvI-WnJSf4lC_wz0QfPrhOBp8MeEpCiYAOTjQgHYoQHVajD86e6WeMOgQbASMl-uhGCm8jjGo7LQLmkPgCtkN4lM_yamCrXVEUbPUMpyMaUE2rlVRBn0EehTkoc4iuz7HLGIwcl1w8rP866Rgvc8bMyt_y7E_IHHz6IuTxRymktZXRAcKnRIIT8T3Z6q2-tJTEJGuTBjehFNOGl3zUpvxV7NwSNRiGHxLbkNMm5cUY1T4qvfYOfFfl4UAFze4JIUQbAy9Yo89EDMr4JFCESynKx12UUUEJrf7GehhJNS0jIXJILXVBMwtxOLho-hMMcKiExzia-IXGrKMI1OilU1XK3iv0XMmQtj0XMtheOKH9cjCV-8lwdtmNfTIMrCsyl7DV83V4b6NuVfxCeL8WNYR3Bf-iPCS3atwHsC06siHRazKtQZMHgqUgvFv9jhT8ZESWlAhh2n-kCNGLggpujEGKt7GNMiLgNYISWKAR5yw04iRpN-DnBmai56furlDbUwGvFG4zIHnQ7CURG9XLlIIY4E_G1y-kod0TisfZsda8kPy91dqeot9zKZ2yET3zdfIuzGbw_5QBJ-Ujiw7SlQds2nDOYRem_tR2fS-c-CGaVhMZzbdvjK-vCtykXo65U9tYjCuUthnIlvH14OShW_RBOOrmXKxsSUgT7ZjKU2lyjVIL17cgQwLHHjMnX2R9_EisTy_6CnA1nbbKpZjYo7eibyOslJ1zWBeMb96uEogogfDGy_uR0e6_nz1fyLkoo31znvOF2t9u0F-kgknrprnQOtUUqh6J5laGDAE4irZFA2If0GUpqcQ7IdEPS_CG_-jtqIGaHCoy-LaU6ETHCdijNWroJjPWvyo_i_nomsVv1p9LWYObt9HyawoYez-CROoqibcq3Nu-rgbrxAHhdFTymIVNyhdBqFVEzR4cdh5rgqNDjcJjHZkoFmM8fW5jesoLFxtFbiffxx3TXk4dlBH606ak63RClti30sJDcML4Vjg01B05bLWQKCqNUJ1Tezpolhr41iqTXCVCFpde1dSn39AmLRsREoEXH93nNRcK5mSOWohmaJivrT0prUF0wTbUEwkd7cgt5BiPiYeJDUl00uaa9C-mUtgjOcVYZXG5M4_BDHbalV6u_mFLtf5NHK9H7K7hT9UoLZyO_fMEnF9jORsVz_piwP4FmKcwjj6OsDrnIxexxdBupnsD8T_Joe9lD9WLg07nqxFZ_gssUs0fQkemR15SBrRqFBlyEmffF_R-DfGZG48ykfZcOrCkR9LDI04atjp1csVldfadPIIY1J2cbgdH9p6YHl19kEV9NqJRssgz-w5y0zeDne_PNK2jHiooHIrxhXtyTa6xxUjLse6lceXhhFrPevaOpac_qVHsPt8WgdqPPcm6WOSeZLorFYScKLl3G-ObEvwqS1L1sj4wXvY1a8Z_qwD8d5FDLr1mwtkrR8f0NuQWs7Yhu3s8W-bmRNWzSdNHTOW_vOjo-6UkfrLMH4XW8T6h99w1e3y3neg7tl_o6G8JGTzEVruX9BZKkvTC2XrO1vzzXZ0yARi_3zO-Tndpw9VWHjlMr7vwI6AzkIeUK6dTt6qNV23zi_XKLeLbOM7KHVz_62_3Pl9zllswndZ9OZvK5FFm1NqVSb1vSFWujBl2xjA9XE43KOMGF8YPY8vJ5stf2HyZsk2lxLYnM1EiZ5o8CgcfILQ6GOH74Fwrsuo96zB6qHUY3qTwgZVPOSasfIk23H-Miv5YvVGVCftFfTIhXN13EtwSvjZLKh2Q8TjezPD126-E42245vx8mHEIwiEYm4_Y8XCW68leyHxLcdn2Np2ng87FdQIxHlGrqvt-AHZdoJOn8hcTq_Nwyp1eQt246RzOSvlMclc_lvWm3Ig7fFw8lJtyfr_g5d3xUa7mlVjN9yjm8xKX6-VmvhGSL5frJfJSLu_UI5_z1ZwvFnxernhZrEt-vyzXm6quHu6l2LDlHBuhdKH1e1NYd7iLV_qPC37_sOF3WlSoffz2wLnUwhwY52z1fOceacGs6g6eLeda-eBHEUEFHT9YPKUVRDrEpP8Yu0MLyuSj4vV9DVmfP12kbwmTrxQ-EJn2nyjuOqcfr74yqHDsqkLahvFXUij_mbXOplr0Gg0kOsw2vj_y_wQAAP__XTI9fA">