On 02/25/2016 09:08 AM, Jason Merrill wrote:
We don't bother evaluating a store to an empty class member, and we shouldn't complain about accesses either.
This needs to use really_empty_class, since that's what expand_aggr_init_1 uses.
Tested x86_64-pc-linux-gnu, applying to trunk and 5.
commit 9a1d6b7c9fa018033ff444829ad3c597e61f5120 Author: Jason Merrill <ja...@redhat.com> Date: Wed Mar 2 14:33:54 2016 -0500 PR c++/67364 * constexpr.c (cxx_eval_component_reference): Just return an empty CONSTRUCTOR for an empty class. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index bcb129f..5a81469 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1988,11 +1988,12 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, } if (CONSTRUCTOR_NO_IMPLICIT_ZERO (whole) - && !is_empty_class (TREE_TYPE (part))) + && !is_really_empty_class (TREE_TYPE (t))) { /* 'whole' is part of the aggregate initializer we're currently building; if there's no initializer for this member yet, that's an - error. */ + error. But expand_aggr_init_1 doesn't bother to initialize really + empty classes, so ignore them here, too. */ if (!ctx->quiet) error ("accessing uninitialized member %qD", part); *non_constant_p = true; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-empty11.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty11.C new file mode 100644 index 0000000..7437367 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty11.C @@ -0,0 +1,17 @@ +// PR c++/67364 +// { dg-do compile { target c++11 } } + +template <typename Xn> +struct element : Xn { + constexpr element() : Xn() { } +}; + +template <typename Xn> +struct closure { + element<Xn> member; + constexpr closure() { } +}; + +struct empty { struct {} s; }; +constexpr closure<empty> tup{}; +constexpr empty first = tup.member;