Blame SOURCES/gcc8-rh1960701.patch

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