aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/semantics.c48
-rw-r--r--libgomp/ChangeLog6
-rw-r--r--libgomp/testsuite/libgomp.c++/pr38650.C49
-rw-r--r--libgomp/testsuite/libgomp.c/pr38650.c49
5 files changed, 146 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2771f7e..df04c1b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2008-12-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/38650
+ * semantics.c (finish_omp_for): Don't add CLEANUP_POINT_EXPR
+ around volatile iteration var in condition and/or increment
+ expression.
+
2008-12-27 Jakub Jelinek <jakub@redhat.com>
PR c++/38639
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index d5efb83..62d2462 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4262,13 +4262,25 @@ finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
}
else
init = build2 (MODIFY_EXPR, void_type_node, decl, init);
- if (cond && TREE_SIDE_EFFECTS (cond) && COMPARISON_CLASS_P (cond))
+ if (cond
+ && TREE_SIDE_EFFECTS (cond)
+ && COMPARISON_CLASS_P (cond)
+ && !processing_template_decl)
{
- int n = TREE_SIDE_EFFECTS (TREE_OPERAND (cond, 1)) != 0;
- tree t = TREE_OPERAND (cond, n);
+ tree t = TREE_OPERAND (cond, 0);
+ if (TREE_SIDE_EFFECTS (t)
+ && t != decl
+ && (TREE_CODE (t) != NOP_EXPR
+ || TREE_OPERAND (t, 0) != decl))
+ TREE_OPERAND (cond, 0)
+ = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
- if (!processing_template_decl)
- TREE_OPERAND (cond, n)
+ t = TREE_OPERAND (cond, 1);
+ if (TREE_SIDE_EFFECTS (t)
+ && t != decl
+ && (TREE_CODE (t) != NOP_EXPR
+ || TREE_OPERAND (t, 0) != decl))
+ TREE_OPERAND (cond, 1)
= fold_build_cleanup_point_expr (TREE_TYPE (t), t);
}
if (decl == error_mark_node || init == error_mark_node)
@@ -4292,21 +4304,31 @@ finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++)
{
- tree incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i);
+ decl = TREE_OPERAND (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i), 0);
+ incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i);
if (TREE_CODE (incr) != MODIFY_EXPR)
continue;
if (TREE_SIDE_EFFECTS (TREE_OPERAND (incr, 1))
- && BINARY_CLASS_P (TREE_OPERAND (incr, 1)))
+ && BINARY_CLASS_P (TREE_OPERAND (incr, 1))
+ && !processing_template_decl)
{
- tree t = TREE_OPERAND (incr, 1);
- int n = TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1)) != 0;
+ tree t = TREE_OPERAND (TREE_OPERAND (incr, 1), 0);
+ if (TREE_SIDE_EFFECTS (t)
+ && t != decl
+ && (TREE_CODE (t) != NOP_EXPR
+ || TREE_OPERAND (t, 0) != decl))
+ TREE_OPERAND (TREE_OPERAND (incr, 1), 0)
+ = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
- if (!processing_template_decl)
- TREE_OPERAND (t, n)
- = fold_build_cleanup_point_expr (TREE_TYPE (TREE_OPERAND (t, n)),
- TREE_OPERAND (t, n));
+ t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
+ if (TREE_SIDE_EFFECTS (t)
+ && t != decl
+ && (TREE_CODE (t) != NOP_EXPR
+ || TREE_OPERAND (t, 0) != decl))
+ TREE_OPERAND (TREE_OPERAND (incr, 1), 1)
+ = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
}
if (orig_incr)
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 3859e60..d8e91b3 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,9 @@
+2008-12-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/38650
+ * testsuite/libgomp.c/pr38650.c: New test.
+ * testsuite/libgomp.c++/pr38650.C: New test.
+
2008-12-27 Jakub Jelinek <jakub@redhat.com>
* testsuite/libgomp.c/collapse-1.c (main): Add private(k) clause.
diff --git a/libgomp/testsuite/libgomp.c++/pr38650.C b/libgomp/testsuite/libgomp.c++/pr38650.C
new file mode 100644
index 0000000..ebe221a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/pr38650.C
@@ -0,0 +1,49 @@
+// PR c++/38650
+// { dg-do run }
+
+#include <cstdlib>
+
+int e;
+
+int
+main ()
+{
+ volatile int i, j = 10;
+ e = 0;
+#pragma omp parallel for reduction(+:e)
+ for (i = 0; i < j; i += 1)
+ e++;
+ if (e != 10)
+ std::abort ();
+ e = 0;
+#pragma omp parallel for reduction(+:e)
+ for (i = 0; i < j; ++i)
+ e++;
+ if (e != 10)
+ std::abort ();
+ e = 0;
+#pragma omp parallel for reduction(+:e)
+ for (i = 0; i < j; i++)
+ e++;
+ if (e != 10)
+ std::abort ();
+ e = 0;
+#pragma omp parallel for reduction(+:e)
+ for (i = 0; i < 10; i += 1)
+ e++;
+ if (e != 10)
+ std::abort ();
+ e = 0;
+#pragma omp parallel for reduction(+:e)
+ for (i = 0; i < 10; ++i)
+ e++;
+ if (e != 10)
+ std::abort ();
+ e = 0;
+#pragma omp parallel for reduction(+:e)
+ for (i = 0; i < 10; i++)
+ e++;
+ if (e != 10)
+ std::abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pr38650.c b/libgomp/testsuite/libgomp.c/pr38650.c
new file mode 100644
index 0000000..7066239
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pr38650.c
@@ -0,0 +1,49 @@
+/* PR c++/38650 */
+/* { dg-do run } */
+
+#include <stdlib.h>
+
+int e;
+
+int
+main ()
+{
+ volatile int i, j = 10;
+ e = 0;
+#pragma omp parallel for reduction(+:e)
+ for (i = 0; i < j; i += 1)
+ e++;
+ if (e != 10)
+ abort ();
+ e = 0;
+#pragma omp parallel for reduction(+:e)
+ for (i = 0; i < j; ++i)
+ e++;
+ if (e != 10)
+ abort ();
+ e = 0;
+#pragma omp parallel for reduction(+:e)
+ for (i = 0; i < j; i++)
+ e++;
+ if (e != 10)
+ abort ();
+ e = 0;
+#pragma omp parallel for reduction(+:e)
+ for (i = 0; i < 10; i += 1)
+ e++;
+ if (e != 10)
+ abort ();
+ e = 0;
+#pragma omp parallel for reduction(+:e)
+ for (i = 0; i < 10; ++i)
+ e++;
+ if (e != 10)
+ abort ();
+ e = 0;
+#pragma omp parallel for reduction(+:e)
+ for (i = 0; i < 10; i++)
+ e++;
+ if (e != 10)
+ abort ();
+ return 0;
+}