Consider the following snippet trimmed down to illustrate the problem:
#include <cstdio>
struct A {
union {
struct { int a0, a1; } aa;
int bb[2];
};
#if 1 //bug
constexpr A(int a0, int a1) : aa{a0, a1} {}
#else //OK
constexpr A(int a0, int a1) : bb{a0, a1} {}
#endif
};
int main() {
A t0{2, 3}; std::printf("%d %d\n", t0.aa.a0, t0.aa.a1); //2 3 (OK)
static A t1{2, 3}; std::printf("%d %d\n", t1.aa.a0, t1.aa.a1); //2 3 (OK)
constexpr A t2{2, 3}; std::printf("%d %d\n", t2.aa.a0, t2.aa.a1); //2 3 (OK)
static constexpr A t3{2, 3}; std::printf("%d %d\n", t3.aa.a0, t3.aa.a1); //0 0 (??)
}
msvc 2015 update 3 and 2017 rc1 silently generate incorrect code by zero-initializing t3 instead of properly initializing it with the given values. gcc and clang are fine.
I looked into reporting a bug but it is too much hassle (I don't use the IDE). If you care, please confirm this is a bug, and let it be known to whom it may concern at microsoft.