From 239371f9c700813d7e7be7f34959850bd36a720f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 6 Nov 2007 09:26:50 +0100 Subject: [PATCH] re PR c++/33894 (pragma omp atomic broken) PR c++/33894 * cp-tree.h: Update comment - TYPE_LANG_FLAG_0 is not OMP_ATOMIC_DEPENDENT_P in OMP_ATOMIC. * pt.c (tsubst_expr): Assert OMP_ATOMIC_DEPENDENT_P. * semantics.c (finish_omp_atomic): Revert most of the 2007-02-05 changes, just keep the new representation of OMP_ATOMIC_DEPENDENT_P OMP_ATOMIC. * testsuite/libgomp.c++/atomic-1.C: New test. From-SVN: r129919 --- gcc/cp/ChangeLog | 10 +++++ gcc/cp/cp-tree.h | 1 - gcc/cp/pt.c | 14 +++---- gcc/cp/semantics.c | 38 ++++++++++------- libgomp/ChangeLog | 5 +++ libgomp/testsuite/libgomp.c++/atomic-1.C | 53 ++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 22 deletions(-) create mode 100644 libgomp/testsuite/libgomp.c++/atomic-1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cbd2380fc15..7f49a7262b2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2007-11-06 Jakub Jelinek + + PR c++/33894 + * cp-tree.h: Update comment - TYPE_LANG_FLAG_0 is not + OMP_ATOMIC_DEPENDENT_P in OMP_ATOMIC. + * pt.c (tsubst_expr): Assert OMP_ATOMIC_DEPENDENT_P. + * semantics.c (finish_omp_atomic): Revert most of the + 2007-02-05 changes, just keep the new representation of + OMP_ATOMIC_DEPENDENT_P OMP_ATOMIC. + 2007-11-05 H.J. Lu PR c++/33871 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8fad9150178..5f43c13d3d8 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -53,7 +53,6 @@ struct diagnostic_info; TYPENAME_IS_ENUM_P (in TYPENAME_TYPE) REFERENCE_REF_P (in INDIRECT_EXPR) QUALIFIED_NAME_IS_TEMPLATE (in SCOPE_REF) - OMP_ATOMIC_DEPENDENT_P (in OMP_ATOMIC) OMP_FOR_GIMPLIFYING_P (in OMP_FOR) BASELINK_QUALIFIED_P (in BASELINK) TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9c29f81cc5d..53edd31cd33 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10358,13 +10358,13 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, break; case OMP_ATOMIC: - if (OMP_ATOMIC_DEPENDENT_P (t)) - { - tree op1 = TREE_OPERAND (t, 1); - tree lhs = RECUR (TREE_OPERAND (op1, 0)); - tree rhs = RECUR (TREE_OPERAND (op1, 1)); - finish_omp_atomic (TREE_CODE (op1), lhs, rhs); - } + gcc_assert (OMP_ATOMIC_DEPENDENT_P (t)); + { + tree op1 = TREE_OPERAND (t, 1); + tree lhs = RECUR (TREE_OPERAND (op1, 0)); + tree rhs = RECUR (TREE_OPERAND (op1, 1)); + finish_omp_atomic (TREE_CODE (op1), lhs, rhs); + } break; case EXPR_PACK_EXPANSION: diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 815390c7671..3f45f712e0e 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3909,28 +3909,38 @@ finish_omp_for (location_t locus, tree decl, tree init, tree cond, void finish_omp_atomic (enum tree_code code, tree lhs, tree rhs) { + tree orig_lhs; + tree orig_rhs; + bool dependent_p; tree stmt; - if (processing_template_decl - && (type_dependent_expression_p (lhs) - || type_dependent_expression_p (rhs))) - stmt = build2 (OMP_ATOMIC, void_type_node, integer_zero_node, - build2 (code, void_type_node, lhs, rhs)); - else + 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) { - /* 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); } - - stmt = c_finish_omp_atomic (code, lhs, rhs); } - - if (stmt != error_mark_node) - add_stmt (stmt); + 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, integer_zero_node, + build2 (code, void_type_node, orig_lhs, orig_rhs)); + add_stmt (stmt); } void diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 2f86c483603..3a7d2f5d53e 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,8 @@ +2007-11-06 Jakub Jelinek + + PR c++/33894 + * testsuite/libgomp.c++/atomic-1.C: New test. + 2007-10-25 Jakub Jelinek PR libgomp/33275 diff --git a/libgomp/testsuite/libgomp.c++/atomic-1.C b/libgomp/testsuite/libgomp.c++/atomic-1.C new file mode 100644 index 00000000000..73f6e7c4059 --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/atomic-1.C @@ -0,0 +1,53 @@ +// PR c++/33894 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (); + +int check; + +template void +foo () +{ + #pragma omp atomic + check |= sizeof (T); +} + +template void +bar (T *x, T y) +{ + #pragma omp atomic + *x += y; +} + +template void +baz () +{ + #pragma omp atomic + check++; +} + +int +main () +{ + int i = 0; + long l = 0; + + check = 0; + foo (); + if (check != sizeof (char)) + abort (); + foo (); + if (check != (sizeof (char) | sizeof (short))) + abort (); + bar(&i, 4); + bar(&l, 8L); + if (i != 4 || l != 8L) + abort (); + baz (); + if (check != (sizeof (char) | sizeof (short)) + 1) + abort (); + baz (); + if (check != (sizeof (char) | sizeof (short)) + 2) + abort (); +}