--- gcc/cp/call.c +++ gcc/cp/call.c @@ -6904,7 +6904,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); array = build_array_of_n_type (elttype, len); - array = finish_compound_literal (array, new_ctor, complain, fcl_c99); + array = finish_compound_literal (array, new_ctor, complain); /* Take the address explicitly rather than via decay_conversion to avoid the error about taking the address of a temporary. */ array = cp_build_addr_expr (array, complain); @@ -10984,13 +10984,11 @@ set_up_extended_ref_temp (tree decl, tree expr, vec **cleanups, lvalue-rvalue conversion applied to "a glvalue of literal type that refers to a non-volatile temporary object initialized with a constant expression". Rather than try to communicate - that this VAR_DECL is a temporary, just mark it constexpr. - - Currently this is only useful for initializer_list temporaries, - since reference vars can't appear in constant expressions. */ + that this VAR_DECL is a temporary, just mark it constexpr. */ DECL_DECLARED_CONSTEXPR_P (var) = true; DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = true; TREE_CONSTANT (var) = true; + TREE_READONLY (var) = true; } DECL_INITIAL (var) = init; init = NULL_TREE; --- gcc/cp/tree.c +++ gcc/cp/tree.c @@ -442,6 +442,14 @@ build_target_expr (tree decl, tree value, tsubst_flags_t complain) || useless_type_conversion_p (TREE_TYPE (decl), TREE_TYPE (value))); + /* Set TREE_READONLY for optimization, such as gimplify_init_constructor + moving a constant aggregate into .rodata. */ + if (CP_TYPE_CONST_NON_VOLATILE_P (type) + && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) + && !VOID_TYPE_P (TREE_TYPE (value)) + && reduced_constant_expression_p (value)) + TREE_READONLY (decl) = true; + if (complain & tf_no_cleanup) /* The caller is building a new-expr and does not need a cleanup. */ t = NULL_TREE; --- /dev/null +++ gcc/testsuite/g++.dg/cpp1y/pr95226.C @@ -0,0 +1,17 @@ +// PR c++/95226 +// { dg-do run { target c++14 } } + +#include + +struct T { + unsigned a; + float b {8.}; +}; + +int main() +{ + T t = {1}; + std::vector tt = {{1}, {2}}; + if (t.a != 1 || t.b != 8.0f || tt[0].a != 1 || tt[0].b != 8.0f || tt[1].a != 2 || tt[1].b != 8.0f) + __builtin_abort (); +}