Blame SOURCES/gcc8-rh1960701.patch

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