https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98122
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jason at gcc dot gnu.org --- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- --- gcc/cp/constexpr.c.jj 2020-12-03 15:43:00.491620290 +0100 +++ gcc/cp/constexpr.c 2020-12-04 13:02:06.874418746 +0100 @@ -4679,7 +4679,8 @@ cxx_fold_indirect_ref_1 (location_t loc, } } /* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */ - else if (TREE_CODE (optype) == RECORD_TYPE) + else if (TREE_CODE (optype) == RECORD_TYPE + || TREE_CODE (optype) == UNION_TYPE) { for (tree field = TYPE_FIELDS (optype); field; field = DECL_CHAIN (field)) would fix this, but wonder if for unions we don't need to take into account the currently active member. In: union U { int a; char b; }; constexpr bool foo () { U f { .b = 42 }; constexpr auto m = &U::a; return (f.*m) == 42; } static_assert (foo (), ""); we even with the patch properly reject it: pr98122-2.C:11:20: error: non-constant condition for static assertion 11 | static_assert (foo (), ""); | ~~~~^~ pr98122-2.C:11:20: in ‘constexpr’ expansion of ‘foo()’ pr98122-2.C:11:20: error: accessing ‘U::a’ member instead of initialized ‘U::b’ member in constant expression But: union U { int a; int b; }; constexpr bool foo () { U f { .b = 42 }; constexpr auto m = &U::b; return (f.*m) == 42; } static_assert (foo (), ""); is rejected too and I think it should be accepted. So I guess for UNION_TYPEs we need to first try the active member and only then fall back to what the code would do after the above patch.