From: Jason Merrill Date: Sun, 13 Nov 2011 00:44:39 +0000 (-0500) Subject: re PR c++/51060 (Temporary object stack space is not re-used) X-Git-Tag: releases/gcc-4.7.0~2214 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d0ad58f94e22dcf877cc359fe8f07e30836c7467;p=thirdparty%2Fgcc.git re PR c++/51060 (Temporary object stack space is not re-used) PR c++/51060 * gimplify.c (gimplify_target_expr): Add a clobber to the cleanup. (gimplify_modify_expr): Don't try to simplify it. * cp/cp-gimplify.c (cp_gimplify_expr): Leave clobbers alone. From-SVN: r181332 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f3e745fcb5e3..e90d1f68944c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-11-12 Jason Merrill + + PR c++/51060 + * gimplify.c (gimplify_target_expr): Add a clobber to the cleanup. + (gimplify_modify_expr): Don't try to simplify it. + 2011-11-12 Dimitrios Apostolou PR bootstrap/51094 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 291487fad63e..21f64476d962 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2011-11-12 Jason Merrill + + PR c++/51060 + * cp-gimplify.c (cp_gimplify_expr): Leave clobbers alone. + 2011-11-11 Ed Smith-Rowland <3dw4rd@verizon.net> PR c++/50976 diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index af45f5918468..9968c3dd7ee1 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -569,7 +569,8 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) else if ((is_gimple_lvalue (op1) || INDIRECT_REF_P (op1) || (TREE_CODE (op1) == CONSTRUCTOR - && CONSTRUCTOR_NELTS (op1) == 0) + && CONSTRUCTOR_NELTS (op1) == 0 + && !TREE_CLOBBER_P (op1)) || (TREE_CODE (op1) == CALL_EXPR && !CALL_EXPR_RETURN_SLOT_OPT (op1))) && is_really_empty_class (TREE_TYPE (op0))) diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 9845b6922117..cfe6696f5904 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -4554,6 +4554,16 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR || TREE_CODE (*expr_p) == INIT_EXPR); + /* Trying to simplify a clobber using normal logic doesn't work, + so handle it here. */ + if (TREE_CLOBBER_P (*from_p)) + { + gcc_assert (!want_value && TREE_CODE (*to_p) == VAR_DECL); + gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p)); + *expr_p = NULL; + return GS_ALL_DONE; + } + /* Insert pointer conversions required by the middle-end that are not required by the frontend. This fixes middle-end type checking for for example gcc.dg/redecl-6.c. */ @@ -5335,6 +5345,8 @@ gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) if (init) { + tree cleanup = NULL_TREE; + /* TARGET_EXPR temps aren't part of the enclosing block, so add it to the temps list. Handle also variable length TARGET_EXPRs. */ if (TREE_CODE (DECL_SIZE (temp)) != INTEGER_CST) @@ -5369,8 +5381,30 @@ gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) /* If needed, push the cleanup for the temp. */ if (TARGET_EXPR_CLEANUP (targ)) - gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ), - CLEANUP_EH_ONLY (targ), pre_p); + { + if (CLEANUP_EH_ONLY (targ)) + gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ), + CLEANUP_EH_ONLY (targ), pre_p); + else + cleanup = TARGET_EXPR_CLEANUP (targ); + } + + /* Add a clobber for the temporary going out of scope, like + gimplify_bind_expr. */ + if (needs_to_live_in_memory (temp)) + { + tree clobber = build_constructor (TREE_TYPE (temp), NULL); + TREE_THIS_VOLATILE (clobber) = true; + clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber); + if (cleanup) + cleanup = build2 (COMPOUND_EXPR, void_type_node, cleanup, + clobber); + else + cleanup = clobber; + } + + if (cleanup) + gimple_push_cleanup (temp, cleanup, false, pre_p); /* Only expand this once. */ TREE_OPERAND (targ, 3) = init; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9f151d1c08b6..0582e49e0e5c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-11-12 Jason Merrill + + PR c++/51060 + * g++.dg/opt/stack2.C: New. + 2011-11-12 Uros Bizjak * lib/gcc-simulate-thread.exp (simulate-thread): Do not run on diff --git a/gcc/testsuite/g++.dg/opt/stack2.C b/gcc/testsuite/g++.dg/opt/stack2.C new file mode 100644 index 000000000000..8468e1a68832 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/stack2.C @@ -0,0 +1,33 @@ +// PR c++/51060 +// { dg-options "-Os -Wframe-larger-than=2000 -Werror" } + +// Shows a problem of not re-using stack space: +// Compile as: g++ -c test_stack_reuse.cpp -o /dev/null -Wframe-larger-than=2048 -Werror -Os +// Result: warning: the frame size of 10240 bytes is larger than 2048 bytes [-Wframe-larger-than=] +// + +struct StackObject +{ + StackObject(); + char buffer[1024]; +}; + +void Test() +{ +#define TEST_SUB() \ + StackObject(); + +#define TEST() \ + TEST_SUB() \ + TEST_SUB() \ + TEST_SUB() \ + TEST_SUB() \ + TEST_SUB() \ + TEST_SUB() \ + TEST_SUB() \ + TEST_SUB() \ + TEST_SUB() \ + TEST_SUB() + + TEST() +} diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 22663da3cac8..782284365b3a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2011-11-12 Jason Merrill + + PR c++/51060 + * testsuite/25_algorithms/max/1.cc (test01): Drop references. + * testsuite/25_algorithms/min/1.cc (test01): Drop references. + * testsuite/25_algorithms/minmax/1.cc (test01): Drop references. + 2011-11-12 Jonathan Wakely PR libstdc++/51083 diff --git a/libstdc++-v3/testsuite/25_algorithms/max/1.cc b/libstdc++-v3/testsuite/25_algorithms/max/1.cc index 978466f1b076..1757b6a49f6b 100644 --- a/libstdc++-v3/testsuite/25_algorithms/max/1.cc +++ b/libstdc++-v3/testsuite/25_algorithms/max/1.cc @@ -25,13 +25,13 @@ void test01() { bool test __attribute__((unused)) = true; - const int& x = std::max(1, 2); - const int& y = std::max(4, 3); + const int x = std::max(1, 2); + const int y = std::max(4, 3); VERIFY( x == 2 ); VERIFY( y == 4 ); - const int& xc = std::max(1, 2, std::greater()); - const int& yc = std::max(4, 3, std::greater()); + const int xc = std::max(1, 2, std::greater()); + const int yc = std::max(4, 3, std::greater()); VERIFY( xc == 1 ); VERIFY( yc == 3 ); } diff --git a/libstdc++-v3/testsuite/25_algorithms/min/1.cc b/libstdc++-v3/testsuite/25_algorithms/min/1.cc index 23bc7216173c..ca52e4972451 100644 --- a/libstdc++-v3/testsuite/25_algorithms/min/1.cc +++ b/libstdc++-v3/testsuite/25_algorithms/min/1.cc @@ -25,13 +25,13 @@ void test01() { bool test __attribute__((unused)) = true; - const int& z = std::min(1, 2); - const int& w = std::min(4, 3); + const int z = std::min(1, 2); + const int w = std::min(4, 3); VERIFY( z == 1 ); VERIFY( w == 3 ); - const int& zc = std::min(1, 2, std::greater()); - const int& wc = std::min(4, 3, std::greater()); + const int zc = std::min(1, 2, std::greater()); + const int wc = std::min(4, 3, std::greater()); VERIFY( zc == 2 ); VERIFY( wc == 4 ); } diff --git a/libstdc++-v3/testsuite/25_algorithms/minmax/1.cc b/libstdc++-v3/testsuite/25_algorithms/minmax/1.cc index 52122415e700..5e581927d699 100644 --- a/libstdc++-v3/testsuite/25_algorithms/minmax/1.cc +++ b/libstdc++-v3/testsuite/25_algorithms/minmax/1.cc @@ -27,15 +27,15 @@ void test01() { bool test __attribute__((unused)) = true; - std::pair z = std::minmax(1, 2); - std::pair w = std::minmax(4, 3); + std::pair z = std::minmax(1, 2); + std::pair w = std::minmax(4, 3); VERIFY( z.first == 1 ); VERIFY( z.second == 2 ); VERIFY( w.first == 3 ); VERIFY( w.second == 4 ); - std::pair zc = std::minmax(1, 2, std::greater()); - std::pair wc = std::minmax(4, 3, std::greater()); + std::pair zc = std::minmax(1, 2, std::greater()); + std::pair wc = std::minmax(4, 3, std::greater()); VERIFY( zc.first == 2 ); VERIFY( zc.second == 1 ); VERIFY( wc.first == 4 );