re PR c++/33894 (pragma omp atomic broken)
authorJakub Jelinek <jakub@redhat.com>
Tue, 6 Nov 2007 08:26:50 +0000 (09:26 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 6 Nov 2007 08:26:50 +0000 (09:26 +0100)
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
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/semantics.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c++/atomic-1.C [new file with mode: 0644]

index cbd2380fc1566d52c3de30ab72926b9353e7525a..7f49a7262b2e7b3a57dff42000f82c9f745f6d58 100644 (file)
@@ -1,3 +1,13 @@
+2007-11-06  Jakub Jelinek  <jakub@redhat.com>
+
+       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  <hongjiu.lu@intel.com>
 
        PR c++/33871
index 8fad9150178bddf6dccde01c6670439e74d277a0..5f43c13d3d8ddfbfbe97dda330062414563c5e62 100644 (file)
@@ -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)
index 9c29f81cc5d4b39701248bea1c2b460d97eed3f7..53edd31cd337c2f29875035406411a9ee71533e8 100644 (file)
@@ -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:
index 815390c7671c094af32d3712fd861c63c364e2f3..3f45f712e0e7d8f36fef7889bb137b92cbe2a46c 100644 (file)
@@ -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);
        }
-
+    }
+  if (!dependent_p)
+    {
       stmt = c_finish_omp_atomic (code, lhs, rhs);
+      if (stmt == error_mark_node)
+       return;
     }
-    
-  if (stmt != error_mark_node)
-    add_stmt (stmt);
+  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
index 2f86c483603c8d91c3d8bb398fd43c009dc9a48c..3a7d2f5d53ef8e7aa3b5cead8426f1e32221d84b 100644 (file)
@@ -1,3 +1,8 @@
+2007-11-06  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/33894
+       * testsuite/libgomp.c++/atomic-1.C: New test.
+
 2007-10-25  Jakub Jelinek  <jakub@redhat.com>
 
        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 (file)
index 0000000..73f6e7c
--- /dev/null
@@ -0,0 +1,53 @@
+// PR c++/33894
+// { dg-do run }
+// { dg-options "-O2" }
+
+extern "C" void abort ();
+
+int check;
+
+template<typename T> void
+foo ()
+{
+  #pragma omp atomic
+  check |= sizeof (T);
+}
+
+template<typename T> void
+bar (T *x, T y)
+{
+  #pragma omp atomic
+  *x += y;
+}
+
+template<typename T> void
+baz ()
+{
+  #pragma omp atomic
+  check++;
+}
+
+int
+main ()
+{
+  int i = 0;
+  long l = 0;
+
+  check = 0;
+  foo<char> ();
+  if (check != sizeof (char))
+    abort ();
+  foo<short> ();
+  if (check != (sizeof (char) | sizeof (short)))
+    abort ();
+  bar(&i, 4);
+  bar(&l, 8L);
+  if (i != 4 || l != 8L)
+    abort ();
+  baz<char> ();
+  if (check != (sizeof (char) | sizeof (short)) + 1)
+    abort ();
+  baz<long double> ();
+  if (check != (sizeof (char) | sizeof (short)) + 2)
+    abort ();
+}