This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix #pragma omp atomic in templates (PR c++/33894)


Hi!

The
2007-02-05  Paolo Bonzini  <bonzini@gnu.org>

        * cp-tree.h (OMP_ATOMIC_CODE): Delete.
        (OMP_ATOMIC_DEPENDENT_P): Rewrite.
        * pt.c (tsubst_expr): Adjust for new format of dependent OMP_ATOMIC
        expressions.
        * semantics.c (finish_omp_atomic): Store a whole expression node
        in operand 1, and integer_zero_node in operand 0, for dependent
        OMP_ATOMIC.  Rewrite to make flow easier to understand.
patch broke #pragma omp atomic in templates if not type dependent.

Before that change if #pragma omp atomic was seen in a template,
but neither lhs nor rhs was type dependent, g++ called c_finish_omp_atomic
on build_non_dependent_expr guarded arguments to diagnose broken usage
in templates and if that returned error_mark_node, would just remove it.
But if that call succeeded, it created OMP_ATOMIC_DEPENDENT_P OMP_ATOMIC
anyway.
After this patch it just sticks a normal OMP_ATOMIC into the template
body, but the arguments are possibly NON_DEPENDENT_EXPRs.
Furthermore the changed pt.c just threw all non-OMP_ATOMIC_DEPENDENT_P
OMP_ATOMIC statements on the floor.
The following patch fixes this by reverting to the old handling, except
for a different representation of OMP_ATOMIC_DEPENDENT_P OMP_ATOMIC.

Ok for trunk?

2007-10-26  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.

	* testsuite/libgomp.c++/atomic-1.C: New test.

--- gcc/cp/cp-tree.h.jj	2007-10-26 13:45:43.000000000 +0200
+++ gcc/cp/cp-tree.h	2007-10-26 19:34:47.000000000 +0200
@@ -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)
--- gcc/cp/pt.c.jj	2007-10-22 21:08:38.000000000 +0200
+++ gcc/cp/pt.c	2007-10-26 21:14:11.000000000 +0200
@@ -10302,13 +10302,13 @@ tsubst_expr (tree t, tree args, tsubst_f
       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:
--- gcc/cp/semantics.c.jj	2007-10-22 04:38:45.000000000 +0200
+++ gcc/cp/semantics.c	2007-10-26 20:56:26.000000000 +0200
@@ -3909,28 +3909,38 @@ finish_omp_for (location_t locus, tree d
 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
--- libgomp/testsuite/libgomp.c++/atomic-1.C.jj	2007-10-26 19:35:58.000000000 +0200
+++ libgomp/testsuite/libgomp.c++/atomic-1.C	2007-10-26 19:42:25.000000000 +0200
@@ -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 ();
+}


	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]