65 lines
2.4 KiB
Diff
65 lines
2.4 KiB
Diff
--- 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 ();
|
|
+}
|