aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/semantics.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r--gcc/cp/semantics.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 94e6b18..35a7b9f 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -9877,14 +9877,15 @@ finish_omp_for_block (tree bind, tree omp_for)
void
finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
- tree lhs, tree rhs, tree v, tree lhs1, tree rhs1,
- tree clauses, enum omp_memory_order mo)
+ tree lhs, tree rhs, tree v, tree lhs1, tree rhs1, tree r,
+ tree clauses, enum omp_memory_order mo, bool weak)
{
tree orig_lhs;
tree orig_rhs;
tree orig_v;
tree orig_lhs1;
tree orig_rhs1;
+ tree orig_r;
bool dependent_p;
tree stmt;
@@ -9893,6 +9894,7 @@ finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
orig_v = v;
orig_lhs1 = lhs1;
orig_rhs1 = rhs1;
+ orig_r = r;
dependent_p = false;
stmt = NULL_TREE;
@@ -9904,7 +9906,10 @@ finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
|| (rhs && type_dependent_expression_p (rhs))
|| (v && type_dependent_expression_p (v))
|| (lhs1 && type_dependent_expression_p (lhs1))
- || (rhs1 && type_dependent_expression_p (rhs1)));
+ || (rhs1 && type_dependent_expression_p (rhs1))
+ || (r
+ && r != void_list_node
+ && type_dependent_expression_p (r)));
if (clauses)
{
gcc_assert (TREE_CODE (clauses) == OMP_CLAUSE
@@ -9925,17 +9930,19 @@ finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
lhs1 = build_non_dependent_expr (lhs1);
if (rhs1)
rhs1 = build_non_dependent_expr (rhs1);
+ if (r && r != void_list_node)
+ r = build_non_dependent_expr (r);
}
}
if (!dependent_p)
{
bool swapped = false;
- if (rhs1 && cp_tree_equal (lhs, rhs))
+ if (rhs1 && opcode != COND_EXPR && cp_tree_equal (lhs, rhs))
{
std::swap (rhs, rhs1);
swapped = !commutative_tree_code (opcode);
}
- if (rhs1 && !cp_tree_equal (lhs, rhs1))
+ if (rhs1 && opcode != COND_EXPR && !cp_tree_equal (lhs, rhs1))
{
if (code == OMP_ATOMIC)
error ("%<#pragma omp atomic update%> uses two different "
@@ -9956,7 +9963,7 @@ finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
return;
}
stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs,
- v, lhs1, rhs1, NULL_TREE, swapped, mo, false,
+ v, lhs1, rhs1, r, swapped, mo, weak,
processing_template_decl != 0);
if (stmt == error_mark_node)
return;
@@ -9973,6 +9980,16 @@ finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
{
if (opcode == NOP_EXPR)
stmt = build2 (MODIFY_EXPR, void_type_node, orig_lhs, orig_rhs);
+ else if (opcode == COND_EXPR)
+ {
+ stmt = build2 (EQ_EXPR, boolean_type_node, orig_lhs, orig_rhs);
+ if (orig_r)
+ stmt = build2 (MODIFY_EXPR, boolean_type_node, orig_r,
+ stmt);
+ stmt = build3 (COND_EXPR, void_type_node, stmt, orig_rhs1,
+ orig_lhs);
+ orig_rhs1 = NULL_TREE;
+ }
else
stmt = build2 (opcode, void_type_node, orig_lhs, orig_rhs);
if (orig_rhs1)
@@ -9982,12 +9999,14 @@ finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
{
stmt = build_min_nt_loc (loc, code, orig_lhs1, stmt);
OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
+ OMP_ATOMIC_WEAK (stmt) = weak;
stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt);
}
}
stmt = build2 (OMP_ATOMIC, void_type_node,
clauses ? clauses : integer_zero_node, stmt);
OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
+ OMP_ATOMIC_WEAK (stmt) = weak;
SET_EXPR_LOCATION (stmt, loc);
}