diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 07fbafa3500..2999fc30c9f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2018-05-30 Jason Merrill + PR c++/85873 - constant initializer_list array not in .rodata. + * tree.c (build_target_expr): Set TREE_READONLY. + * call.c (set_up_extended_ref_temp): Set TREE_READONLY. + * parser.c (cp_parser_check_condition_declarator): Handle cp_error_declarator. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 2bbf9837487..67e404d1cb2 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -10923,13 +10923,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; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index f21daaca1d0..53bc9c7176f 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -461,6 +461,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; diff --git a/gcc/testsuite/g++.dg/tree-ssa/array-temp1.C b/gcc/testsuite/g++.dg/tree-ssa/array-temp1.C new file mode 100644 index 00000000000..97c2e0521c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/array-temp1.C @@ -0,0 +1,21 @@ +// PR c++/85873 +// Test that these array temporaries are promoted to static variables as an +// optimization. + +// { dg-do compile { target c++11 } } +// { dg-additional-options -fdump-tree-gimple } +// { dg-final { scan-tree-dump-not "= 42" "gimple" } } + +#include + +int f() +{ + using AR = const int[]; + return AR{ 1,42,3,4,5,6,7,8,9,0 }[5]; +} + +int g() +{ + std::initializer_list a = {1,42,3}; + return a.begin()[0]; +}