aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2006-06-29 11:49:07 +0000
committerJakub Jelinek <jakub@redhat.com>2006-06-29 11:49:07 +0000
commit78098438234fc908b353f2f77a323aa219397a7e (patch)
tree2fadc7735617513c6d64ade03e4a18fe06e90e07
parent51050b2d23b13296ca3c1c0f9d08a22a5b606750 (diff)
2006-06-14 Mark Mitchell <mark@codesourcery.com>
PR c++/26559 * c-common.h (c_finish_omp_atomic): Adjust declaration. * c-omp.c (c_finish_omp_atomic): Return the expression to perform, rather than calling add_stmt on it. * c-parser.c (c_parser_omp_atomic): Adjust accordingly. * pt.c (tsubst_expr): Use finish_omp_atomic. * semantics.c (finish_omp_atomic): Rework to use standard paradigms for handling non-dependent expressions. * g++.dg/gomp/tpl-atomic-2.C: Remove XFAIL. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/redhat/gcc-4_1-branch@115067 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/c-common.h2
-rw-r--r--gcc/c-omp.c17
-rw-r--r--gcc/c-parser.c5
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/cp/semantics.c47
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/gomp/tpl-atomic-2.C3
9 files changed, 69 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4f1c44f5a42..df5df869e25 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2006-06-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/26559
+ * c-common.h (c_finish_omp_atomic): Adjust declaration.
+ * c-omp.c (c_finish_omp_atomic): Return the expression to perform,
+ rather than calling add_stmt on it.
+ * c-parser.c (c_parser_omp_atomic): Adjust accordingly.
+
2006-06-25 Eric Botcazou <ebotcazou@adacore.com>
PR middle-end/28151
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 1de56a20d3f..191954bf9ab 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -940,7 +940,7 @@ extern tree c_finish_omp_master (tree);
extern tree c_finish_omp_critical (tree, tree);
extern tree c_finish_omp_ordered (tree);
extern void c_finish_omp_barrier (void);
-extern void c_finish_omp_atomic (enum tree_code, tree, tree);
+extern tree c_finish_omp_atomic (enum tree_code, tree, tree);
extern void c_finish_omp_flush (void);
extern tree c_finish_omp_for (location_t, tree, tree, tree, tree, tree, tree);
extern void c_split_parallel_clauses (tree, tree *, tree *);
diff --git a/gcc/c-omp.c b/gcc/c-omp.c
index ac107e67737..fe56824401c 100644
--- a/gcc/c-omp.c
+++ b/gcc/c-omp.c
@@ -82,15 +82,18 @@ c_finish_omp_barrier (void)
/* Complete a #pragma omp atomic construct. The expression to be
- implemented atomically is LHS code= RHS. */
+ implemented atomically is LHS code= RHS. The value returned is
+ either error_mark_node (if the construct was erroneous) or an
+ OMP_ATOMIC node which should be added to the current statement tree
+ with add_stmt. */
-void
+tree
c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
{
tree x, type, addr;
if (lhs == error_mark_node || rhs == error_mark_node)
- return;
+ return error_mark_node;
/* ??? According to one reading of the OpenMP spec, complex type are
supported, but there are no atomic stores for any architecture.
@@ -102,7 +105,7 @@ c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
&& !SCALAR_FLOAT_TYPE_P (type))
{
error ("invalid expression type for %<#pragma omp atomic%>");
- return;
+ return error_mark_node;
}
/* ??? Validate that rhs does not overlap lhs. */
@@ -111,7 +114,7 @@ c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
via indirection. */
addr = build_unary_op (ADDR_EXPR, lhs, 0);
if (addr == error_mark_node)
- return;
+ return error_mark_node;
addr = save_expr (addr);
lhs = build_indirect_ref (addr, NULL);
@@ -120,12 +123,12 @@ c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
to do this, and then take it apart again. */
x = build_modify_expr (lhs, code, rhs);
if (x == error_mark_node)
- return;
+ return error_mark_node;
gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
rhs = TREE_OPERAND (x, 1);
/* Punt the actual generation of atomic operations to common code. */
- add_stmt (build2 (OMP_ATOMIC, void_type_node, addr, rhs));
+ return build2 (OMP_ATOMIC, void_type_node, addr, rhs);
}
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 81ce323ee56..5e2b04f10e9 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -7175,6 +7175,7 @@ static void
c_parser_omp_atomic (c_parser *parser)
{
tree lhs, rhs;
+ tree stmt;
enum tree_code code;
c_parser_skip_to_pragma_eol (parser);
@@ -7241,7 +7242,9 @@ c_parser_omp_atomic (c_parser *parser)
rhs = c_parser_expression (parser).value;
break;
}
- c_finish_omp_atomic (code, lhs, rhs);
+ stmt = c_finish_omp_atomic (code, lhs, rhs);
+ if (stmt != error_mark_node)
+ add_stmt (stmt);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 35acdb07ae0..af05ffd3d65 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2006-06-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/26559
+ * pt.c (tsubst_expr): Use finish_omp_atomic.
+ * semantics.c (finish_omp_atomic): Rework to use standard
+ paradigms for handling non-dependent expressions.
+
2006-06-25 Lee Millward <lee.millward@gmail.com>
PR c++/27821
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 5d0c9a74370..e69a90feba2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8579,10 +8579,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
tree op0, op1;
op0 = tsubst_expr (TREE_OPERAND (t, 0), args, complain, in_decl);
op1 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl);
- if (OMP_ATOMIC_DEPENDENT_P (t))
- c_finish_omp_atomic (OMP_ATOMIC_CODE (t), op0, op1);
- else
- add_stmt (build2 (OMP_ATOMIC, void_type_node, op0, op1));
+ finish_omp_atomic (OMP_ATOMIC_CODE (t), op0, op1);
}
break;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 31d03109040..bb47616dca7 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3829,24 +3829,41 @@ finish_omp_for (location_t locus, tree decl, tree init, tree cond,
void
finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
{
- /* If either of the operands are dependent, we can't do semantic
- processing yet. Stuff the values away for now. We cheat a bit
- and use the same tree code for this, even though the operands
- are of totally different form, thus we need to remember which
- statements are which, thus the lang_flag bit. */
- /* ??? We ought to be using type_dependent_expression_p, but the
- invocation of build_modify_expr in c_finish_omp_atomic can result
- in the creation of CONVERT_EXPRs, which are not handled by
- tsubst_copy_and_build. */
- if (uses_template_parms (lhs) || uses_template_parms (rhs))
- {
- tree stmt = build2 (OMP_ATOMIC, void_type_node, lhs, rhs);
+ tree orig_lhs;
+ tree orig_rhs;
+ bool dependent_p;
+ tree stmt;
+
+ orig_lhs = lhs;
+ orig_rhs = rhs;
+ dependent_p = false;
+ stmt = NULL_TREE;
+
+ /* Even in a template, we can detect invalid uses of the atomic
+ pragma if neither LHS nor RHS is type-dependent. */
+ if (processing_template_decl)
+ {
+ dependent_p = (type_dependent_expression_p (lhs)
+ || type_dependent_expression_p (rhs));
+ if (!dependent_p)
+ {
+ lhs = build_non_dependent_expr (lhs);
+ rhs = build_non_dependent_expr (rhs);
+ }
+ }
+ if (!dependent_p)
+ {
+ stmt = c_finish_omp_atomic (code, lhs, rhs);
+ if (stmt == error_mark_node)
+ return;
+ }
+ if (processing_template_decl)
+ {
+ stmt = build2 (OMP_ATOMIC, void_type_node, orig_lhs, orig_rhs);
OMP_ATOMIC_DEPENDENT_P (stmt) = 1;
OMP_ATOMIC_CODE (stmt) = code;
- add_stmt (stmt);
}
- else
- c_finish_omp_atomic (code, lhs, rhs);
+ add_stmt (stmt);
}
void
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dd0d5a0c724..e11f2b227c2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-06-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/26559
+ * g++.dg/gomp/tpl-atomic-2.C: Remove XFAIL.
+
2006-06-27 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/19310
diff --git a/gcc/testsuite/g++.dg/gomp/tpl-atomic-2.C b/gcc/testsuite/g++.dg/gomp/tpl-atomic-2.C
index 363bd103d8e..c27f2019397 100644
--- a/gcc/testsuite/g++.dg/gomp/tpl-atomic-2.C
+++ b/gcc/testsuite/g++.dg/gomp/tpl-atomic-2.C
@@ -17,11 +17,10 @@ template<typename T> void f2(float *f)
}
// Here the rhs is dependent, but not type dependent.
-// ??? Fails. See the comment in finish_omp_atomic.
template<typename T> void f3(float *f)
{
#pragma omp atomic
- *f |= sizeof (T); // { dg-error "invalid|evaluation" "" { xfail *-*-* } }
+ *f |= sizeof (T); // { dg-error "invalid|evaluation" }
}
// And the converse, no error here because we're never fed a T.