Blob Blame History Raw
--- 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<tree, va_gc> **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 <vector>
+
+struct T {
+  unsigned a;
+  float b {8.};
+};
+
+int main()
+{
+  T t = {1};
+  std::vector<T> 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 ();
+}