diff options
author | pinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-10-11 03:42:09 +0000 |
---|---|---|
committer | pinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-10-11 03:42:09 +0000 |
commit | acbc760afd49666c25ef62103735f2a0182f3abe (patch) | |
tree | ba27ac02d6df5a9d734fba44b00edb8f74204304 | |
parent | a4b48f013b8126cf35f4c8403ddf26cfcc894781 (diff) | |
download | gcc-acbc760afd49666c25ef62103735f2a0182f3abe.tar.gz |
2004-10-10 Andrew Pinski <pinskia@physics.uc.edu>
PR c++/17554
part of c++/17657
middle-end/17703
* semantics.c (maybe_cleanup_point_expr): Call
fold_build_cleanup_point_expr.
(maybe_cleanup_point_expr_void): New function.
(add_decl_expr): Call maybe_cleanup_point_expr_void.
(finish_expr_stmt): Likewise.
(finish_return_stmt): Likewise.
(finish_for_expr): Likewise.
(finish_asm_stmt): Likewise.
* typeck.c (condition_conversion): Call
fold_build_cleanup_point_expr.
2004-10-10 Andrew Pinski <pinskia@physics.uc.edu>
PR middle-end/17703
part of PR c++/17657
* fold-const.c (fold_build_cleanup_point_expr): New function.
* tree.h (fold_build_cleanup_point_expr): Prototype.
2004-10-10 Andrew Pinski <pinskia@physics.uc.edu>
PR c++/17554
* g++.dg/init/for3.C: New test.
PR c++/17657
* g++.dg/opt/switch2.C: New test.
PR middle-end/17703
* g++.dg/warn/Wreturn-2.C: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@88869 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 27 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 2 | ||||
-rw-r--r-- | gcc/fold-const.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/for3.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/switch2.C | 23 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wreturn-2.C | 7 | ||||
-rw-r--r-- | gcc/tree.h | 1 |
10 files changed, 111 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 92e09b793d7..f816b48b58b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2004-10-10 Andrew Pinski <pinskia@physics.uc.edu> + + PR middle-end/17703 + part of PR c++/17657 + * fold-const.c (fold_build_cleanup_point_expr): New function. + * tree.h (fold_build_cleanup_point_expr): Prototype. + 2004-10-10 Eric Christopher <echristo@redhat.com> * dwarf2out.c: Move attribute to subprogram declaration diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d6aca574f7c..08f73ab6e15 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,21 @@ 2004-10-10 Andrew Pinski <pinskia@physics.uc.edu> + PR c++/17554 + part of c++/17657 + middle-end/17703 + * semantics.c (maybe_cleanup_point_expr): Call + fold_build_cleanup_point_expr. + (maybe_cleanup_point_expr_void): New function. + (add_decl_expr): Call maybe_cleanup_point_expr_void. + (finish_expr_stmt): Likewise. + (finish_return_stmt): Likewise. + (finish_for_expr): Likewise. + (finish_asm_stmt): Likewise. + * typeck.c (condition_conversion): Call + fold_build_cleanup_point_expr. + +2004-10-10 Andrew Pinski <pinskia@physics.uc.edu> + PR c++/17907 * semantics.c (add_decl_expr): If the decl has a size which has side effects then the decl expression needs a cleanup point. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 45912c1707b..0fb5c684a8f 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -358,10 +358,25 @@ static tree maybe_cleanup_point_expr (tree expr) { if (!processing_template_decl && stmts_are_full_exprs_p ()) - expr = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (expr), expr); + expr = fold_build_cleanup_point_expr (TREE_TYPE (expr), expr); return expr; } +/* Like maybe_cleanup_point_expr except have the type of the new expression be + void so we don't need to create a temprary variable to hold the inner + expression. The reason why we do this is because the orginal type might be + an aggregate and we cannot create a temprary variable for that type. */ + +static tree +maybe_cleanup_point_expr_void (tree expr) +{ + if (!processing_template_decl && stmts_are_full_exprs_p ()) + expr = fold_build_cleanup_point_expr (void_type_node, expr); + return expr; +} + + + /* Create a declaration statement for the declaration given by the DECL. */ void @@ -370,7 +385,7 @@ add_decl_expr (tree decl) tree r = build_stmt (DECL_EXPR, decl); if (DECL_INITIAL (decl) || (DECL_SIZE (decl) && TREE_SIDE_EFFECTS (DECL_SIZE (decl)))) - r = maybe_cleanup_point_expr (r); + r = maybe_cleanup_point_expr_void (r); add_stmt (r); } @@ -556,7 +571,7 @@ finish_expr_stmt (tree expr) { if (TREE_CODE (expr) != EXPR_STMT) expr = build_stmt (EXPR_STMT, expr); - expr = maybe_cleanup_point_expr (expr); + expr = maybe_cleanup_point_expr_void (expr); } r = add_stmt (expr); @@ -719,7 +734,7 @@ finish_return_stmt (tree expr) } r = build_stmt (RETURN_EXPR, expr); - r = maybe_cleanup_point_expr (r); + r = maybe_cleanup_point_expr_void (r); r = add_stmt (r); finish_stmt (); @@ -783,7 +798,7 @@ finish_for_expr (tree expr, tree for_stmt) cxx_incomplete_type_error (expr, TREE_TYPE (expr)); expr = error_mark_node; } - expr = maybe_cleanup_point_expr (expr); + expr = maybe_cleanup_point_expr_void (expr); FOR_EXPR (for_stmt) = expr; } @@ -1179,7 +1194,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands, output_operands, input_operands, clobbers); ASM_VOLATILE_P (r) = volatile_p; - r = maybe_cleanup_point_expr (r); + r = maybe_cleanup_point_expr_void (r); return add_stmt (r); } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index e59755416ab..dc0b7cd52c5 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3681,7 +3681,7 @@ condition_conversion (tree expr) if (processing_template_decl) return expr; t = perform_implicit_conversion (boolean_type_node, expr); - t = build1 (CLEANUP_POINT_EXPR, boolean_type_node, t); + t = fold_build_cleanup_point_expr (boolean_type_node, t); return t; } diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 41feda3ef1e..1dba1fb6c12 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10465,6 +10465,21 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1) return constant_boolean_node (result, type); } +/* Build an expression for the a clean point containing EXPR with type TYPE. + Don't build a cleanup point expression for EXPR which don't have side + effects. */ + +tree +fold_build_cleanup_point_expr (tree type, tree expr) +{ + /* If the expression does not have side effects then we don't have to wrap + it with a cleanup point expression. */ + if (!TREE_SIDE_EFFECTS (expr)) + return expr; + + return build1 (CLEANUP_POINT_EXPR, type, expr); +} + /* Build an expression for the address of T. Folds away INDIRECT_REF to avoid confusing the gimplify process. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ac9574dff53..632dc18d594 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,16 @@ 2004-10-10 Andrew Pinski <pinskia@physics.uc.edu> + PR c++/17554 + * g++.dg/init/for3.C: New test. + + PR c++/17657 + * g++.dg/opt/switch2.C: New test. + + PR middle-end/17703 + * g++.dg/warn/Wreturn-2.C: New test. + +2004-10-10 Andrew Pinski <pinskia@physics.uc.edu> + PR c++/17907 * g++.dg/eh/cleanup5.C: New test. diff --git a/gcc/testsuite/g++.dg/init/for3.C b/gcc/testsuite/g++.dg/init/for3.C new file mode 100644 index 00000000000..c8ef3cc6291 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/for3.C @@ -0,0 +1,9 @@ +// { dg-do compile } + +struct A { int i; A(); A(const A&); }; + +void bar() +{ + A a; + for ( ;; a=A() ) ; +} diff --git a/gcc/testsuite/g++.dg/opt/switch2.C b/gcc/testsuite/g++.dg/opt/switch2.C new file mode 100644 index 00000000000..2590273c5d9 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/switch2.C @@ -0,0 +1,23 @@ +// { dg-do compile } +// { dg-options "-O2" } + +extern int foo (int); + +void +bar (void) +{ + char tmp = foo (0); + switch (tmp) + { + case 1: foo (1); break; + case 2: foo (2); break; + case 3: foo (3); break; + case 4: foo (4); break; + case 5: foo (5); break; + case 6: foo (6); break; + case 7: foo (7); break; + case 255: foo (8); break; + default: break; + } +} + diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-2.C b/gcc/testsuite/g++.dg/warn/Wreturn-2.C new file mode 100644 index 00000000000..460afd53a8c --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wreturn-2.C @@ -0,0 +1,7 @@ +// { dg-do compile } +int foo(int first) { + while (true) { + return first; + } +} // { dg-bogus "control reaches" } + diff --git a/gcc/tree.h b/gcc/tree.h index 89771afa7d2..ec2ce118df2 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3538,6 +3538,7 @@ extern tree nondestructive_fold_binary_to_constant (enum tree_code, tree, tree, extern tree fold_read_from_constant_string (tree); extern tree int_const_binop (enum tree_code, tree, tree, int); extern tree build_fold_addr_expr (tree); +tree fold_build_cleanup_point_expr (tree type, tree expr); extern tree build_fold_addr_expr_with_type (tree, tree); extern tree build_fold_indirect_ref (tree); extern tree constant_boolean_node (int, tree); |