summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-11 03:42:09 +0000
committerpinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-11 03:42:09 +0000
commitacbc760afd49666c25ef62103735f2a0182f3abe (patch)
treeba27ac02d6df5a9d734fba44b00edb8f74204304
parenta4b48f013b8126cf35f4c8403ddf26cfcc894781 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/cp/ChangeLog16
-rw-r--r--gcc/cp/semantics.c27
-rw-r--r--gcc/cp/typeck.c2
-rw-r--r--gcc/fold-const.c15
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/init/for3.C9
-rw-r--r--gcc/testsuite/g++.dg/opt/switch2.C23
-rw-r--r--gcc/testsuite/g++.dg/warn/Wreturn-2.C7
-rw-r--r--gcc/tree.h1
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);