mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-22 11:41:07 +08:00
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
This commit is contained in:
parent
f2628dce24
commit
d0ad58f94e
@ -1,3 +1,9 @@
|
||||
2011-11-12 Jason Merrill <jason@redhat.com>
|
||||
|
||||
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 <jimis@gmx.net>
|
||||
|
||||
PR bootstrap/51094
|
||||
|
@ -1,3 +1,8 @@
|
||||
2011-11-12 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/51060
|
||||
* cp-gimplify.c (cp_gimplify_expr): Leave clobbers alone.
|
||||
|
||||
2011-11-11 Ed Smith-Rowland <3dw4rd@verizon.net>
|
||||
|
||||
PR c++/50976
|
||||
|
@ -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)))
|
||||
|
@ -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;
|
||||
|
@ -1,3 +1,8 @@
|
||||
2011-11-12 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/51060
|
||||
* g++.dg/opt/stack2.C: New.
|
||||
|
||||
2011-11-12 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
* lib/gcc-simulate-thread.exp (simulate-thread): Do not run on
|
||||
|
33
gcc/testsuite/g++.dg/opt/stack2.C
Normal file
33
gcc/testsuite/g++.dg/opt/stack2.C
Normal file
@ -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()
|
||||
}
|
@ -1,3 +1,10 @@
|
||||
2011-11-12 Jason Merrill <jason@redhat.com>
|
||||
|
||||
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 <jwakely.gcc@gmail.com>
|
||||
|
||||
PR libstdc++/51083
|
||||
|
@ -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<int>());
|
||||
const int& yc = std::max(4, 3, std::greater<int>());
|
||||
const int xc = std::max(1, 2, std::greater<int>());
|
||||
const int yc = std::max(4, 3, std::greater<int>());
|
||||
VERIFY( xc == 1 );
|
||||
VERIFY( yc == 3 );
|
||||
}
|
||||
|
@ -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<int>());
|
||||
const int& wc = std::min(4, 3, std::greater<int>());
|
||||
const int zc = std::min(1, 2, std::greater<int>());
|
||||
const int wc = std::min(4, 3, std::greater<int>());
|
||||
VERIFY( zc == 2 );
|
||||
VERIFY( wc == 4 );
|
||||
}
|
||||
|
@ -27,15 +27,15 @@ void test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
std::pair<const int&, const int&> z = std::minmax(1, 2);
|
||||
std::pair<const int&, const int&> w = std::minmax(4, 3);
|
||||
std::pair<const int, const int> z = std::minmax(1, 2);
|
||||
std::pair<const int, const int> w = std::minmax(4, 3);
|
||||
VERIFY( z.first == 1 );
|
||||
VERIFY( z.second == 2 );
|
||||
VERIFY( w.first == 3 );
|
||||
VERIFY( w.second == 4 );
|
||||
|
||||
std::pair<const int&, const int&> zc = std::minmax(1, 2, std::greater<int>());
|
||||
std::pair<const int&, const int&> wc = std::minmax(4, 3, std::greater<int>());
|
||||
std::pair<const int, const int> zc = std::minmax(1, 2, std::greater<int>());
|
||||
std::pair<const int, const int> wc = std::minmax(4, 3, std::greater<int>());
|
||||
VERIFY( zc.first == 2 );
|
||||
VERIFY( zc.second == 1 );
|
||||
VERIFY( wc.first == 4 );
|
||||
|
Loading…
x
Reference in New Issue
Block a user