From 5603790dbf233c31c60d8877f632c06c4753acfb Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 30 May 2018 13:33:06 -0400 Subject: [PATCH] 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. From-SVN: r260969 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/call.c | 6 ++---- gcc/cp/tree.c | 8 ++++++++ gcc/testsuite/g++.dg/tree-ssa/array-temp1.C | 21 +++++++++++++++++++++ 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/tree-ssa/array-temp1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 07fbafa..2999fc3 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 2bbf983..67e404d 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 f21daac..53bc9c7 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 0000000..97c2e05 --- /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]; +} -- 2.7.4