diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 630c2190a8e..9b36f7628f3 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -3123,10 +3123,16 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, At this point it has already been evaluated in the call to cxx_bind_parameters_in_call. */ new_obj = TREE_VEC_ELT (new_call.bindings, 0); - new_obj = cxx_fold_indirect_ref (ctx, loc, DECL_CONTEXT (fun), new_obj); - - if (ctx->call && ctx->call->fundef - && DECL_CONSTRUCTOR_P (ctx->call->fundef->decl)) + bool empty_base = false; + new_obj = cxx_fold_indirect_ref (ctx, loc, DECL_CONTEXT (fun), new_obj, + &empty_base); + /* If we're initializing an empty class, don't set constness, because + cxx_fold_indirect_ref will return the wrong object to set constness + of. */ + if (empty_base) + new_obj = NULL_TREE; + else if (ctx->call && ctx->call->fundef + && DECL_CONSTRUCTOR_P (ctx->call->fundef->decl)) { tree cur_obj = TREE_VEC_ELT (ctx->call->bindings, 0); STRIP_NOPS (cur_obj); diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-init23.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-init23.C new file mode 100644 index 00000000000..466236d446d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-init23.C @@ -0,0 +1,22 @@ +// PR c++/115900 +// { dg-do compile { target c++20 } } + +struct A { + char m; + constexpr A() { m = 0; } +}; + +struct C { + constexpr C(){ }; +}; + +struct B : C { + A a; + constexpr B() {} +}; + +struct D : B { }; + +static constexpr A a; +static constexpr B b; +static constexpr D d;