finish_omp_for (location_t locus, tree decl, tree init, tree cond,
tree incr, tree body, tree pre_body)
{
+ tree omp_for;
+
if (decl == NULL)
{
if (init != NULL)
add_stmt (pre_body);
pre_body = NULL;
}
+
+ init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
init = build_modify_expr (decl, NOP_EXPR, init);
- return c_finish_omp_for (locus, decl, init, cond, incr, body, pre_body);
+ if (cond && TREE_SIDE_EFFECTS (cond) && COMPARISON_CLASS_P (cond))
+ {
+ int n = TREE_SIDE_EFFECTS (TREE_OPERAND (cond, 1)) != 0;
+ tree t = TREE_OPERAND (cond, n);
+
+ TREE_OPERAND (cond, n)
+ = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
+ omp_for = c_finish_omp_for (locus, decl, init, cond, incr, body, pre_body);
+ if (omp_for != NULL
+ && TREE_CODE (OMP_FOR_INCR (omp_for)) == MODIFY_EXPR
+ && TREE_SIDE_EFFECTS (TREE_OPERAND (OMP_FOR_INCR (omp_for), 1))
+ && BINARY_CLASS_P (TREE_OPERAND (OMP_FOR_INCR (omp_for), 1)))
+ {
+ tree t = TREE_OPERAND (OMP_FOR_INCR (omp_for), 1);
+ int n = TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1)) != 0;
+
+ TREE_OPERAND (t, n)
+ = fold_build_cleanup_point_expr (TREE_TYPE (TREE_OPERAND (t, n)),
+ TREE_OPERAND (t, n));
+ }
+ return omp_for;
}
void
--- /dev/null
+// PR c++/32177
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+//
+// Copyright (C) 2007 Free Software Foundation, Inc.
+// Contributed by Theodore.Papadopoulo 1 Jun 2007 <Theodore.Papadopoulo@sophia.inria.fr>
+
+struct A
+{
+ A () {}
+ ~A () {}
+ int s () const { return 1; }
+};
+
+void
+f1 ()
+{
+ #pragma omp parallel for
+ for (int i = 1; i <= A ().s (); ++i)
+ ;
+}
+
+void
+f2 ()
+{
+ #pragma omp parallel for
+ for (int i = A ().s (); i <= 20; ++i)
+ ;
+}
+
+void
+f3 ()
+{
+ #pragma omp parallel for
+ for (int i = 1; i <= 20; i += A ().s ())
+ ;
+}
+
+void
+f4 ()
+{
+ int i;
+ #pragma omp parallel for
+ for (i = A ().s (); i <= 20; i++)
+ ;
+}