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]

[gomp] fix default(shared) vs nested parallels


Previously we'd ICE because we hadn't injected shared(var) annotations
into all enclosing scopes.


r~


        * c-decl.c (struct c_scope): Add location.
        (define_label): Use lookup_name_no_remap.
        (c_omp_remap_decl_1): Add pscope argument.  Use it instead of
        current_omp_parallel_scope.
        (c_omp_remap_decl): Pass it current_omp_parallel_scope.
        (maybe_remap_for_omp_parallel): New.
        (lookup_name): Use it.
        (c_begin_omp_parallel): Initialize location field.

Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.662.4.9
diff -u -p -d -r1.662.4.9 c-decl.c
--- c-decl.c	29 Sep 2005 09:04:46 -0000	1.662.4.9
+++ c-decl.c	29 Sep 2005 23:02:19 -0000
@@ -332,6 +332,10 @@ struct c_scope GTY((chain_next ("%h.oute
      OpenMP parallel scope.  */
   tree omp_shared;
 
+  /* A locus for the start of the omp parallel block, for use when
+     generating default(none) error messages.  */
+  location_t location;
+
   /* The depth of this scope.  Used to keep the ->shadowed chain of
      bindings sorted innermost to outermost.  */
   unsigned int depth : 28;
@@ -2604,7 +2608,7 @@ define_label (location_t location, tree 
 	    /*invisible=*/false, /*nested=*/false);
     }
 
-  if (!in_system_header && lookup_name (name))
+  if (!in_system_header && lookup_name_no_remap (name))
     warning (OPT_Wtraditional, "%Htraditional C lacks a separate namespace "
              "for labels, identifier %qE conflicts", &location, name);
 
@@ -2757,8 +2761,8 @@ c_omp_sharing_predetermined (tree decl)
 /* Inject a new binding for OLD in scope S.  If SHARED is zero, then we
    want a variable of sharing class private; otherwise we want a variable
    of sharing class shared.  If SHARED is negative, then we're being
-   called from lookup_name and should add the mapping to the currently
-   active parallel construct.
+   called from lookup_name and should add the mapping to the parallel
+   construct PSCOPE.
 
    Sometimes we can optimize away a binding -- global variables being
    marked shared is semantically a no-op.  If FORCE_P is true, this 
@@ -2766,7 +2770,8 @@ c_omp_sharing_predetermined (tree decl)
    generated by default(none).  */
 
 static tree
-c_omp_remap_decl_1 (struct c_scope *s, tree old, int shared, bool force_p)
+c_omp_remap_decl_1 (struct c_scope *s, struct c_scope *pscope,
+		    tree old, int shared, bool force_p)
 {
   tree new;
 
@@ -2789,8 +2794,8 @@ c_omp_remap_decl_1 (struct c_scope *s, t
       tree c = make_node (OMP_CLAUSE_SHARED);
       OMP_CLAUSE_OUTER_DECL (c) = old;
       OMP_CLAUSE_INNER_DECL (c) = new;
-      OMP_CLAUSE_CHAIN (c) = current_omp_parallel_scope->omp_shared;
-      current_omp_parallel_scope->omp_shared = c;
+      OMP_CLAUSE_CHAIN (c) = pscope->omp_shared;
+      pscope->omp_shared = c;
     }
 
   return new;
@@ -2806,7 +2811,45 @@ c_omp_remap_decl (tree old, bool shared_
 
   force_p = (current_omp_parallel_scope
 	     && current_omp_parallel_scope->omp_default_none);
-  return c_omp_remap_decl_1 (current_scope, old, shared_p, force_p);
+  return c_omp_remap_decl_1 (current_scope, NULL, old, shared_p, force_p);
+}
+
+/* A subroutine of lookup_name.  Check whether a use of B needs an error
+   based on default(none) clauses; inject new bindings as needed into
+   omp parallel scopes for variables that need to be shared or private.
+   In all cases, return the binding that's in effect in the current scope
+   after any remapping.  */
+
+static struct c_binding *
+maybe_remap_for_omp_parallel (struct c_scope *pscope, struct c_binding *b)
+{
+  bool did_error = false;
+
+  /* When remapping shared, recurse to the outer-most scope for which the
+     test is relevant.  */
+  if (!omp_remap_private
+      && b->depth < pscope->depth
+      && pscope->outer_omp_parallel)
+    b = maybe_remap_for_omp_parallel (pscope->outer_omp_parallel, b);
+
+  /* Check that the any default(none) clause is honored.  */
+  if (pscope->omp_default_none
+      && c_omp_sharing_implicitly_determined (pscope, b))
+    {
+      error ("%qE not specified in enclosing %<#pragma omp parallel%>", b->id);
+      error ("%Henclosing %<#pragma omp parallel%>", &pscope->location);
+      did_error = true;
+    }
+
+  /* Re-bind the decl to something in scope of the omp parallel.  */
+  if (b->depth < pscope->depth)
+    {
+      int shared = omp_remap_private ? 0 : -1;
+      c_omp_remap_decl_1 (pscope, pscope, b->decl, shared, did_error);
+      b = I_SYMBOL_BINDING (b->id);
+    }
+
+  return b;
 }
 
 /* Look up NAME in the current scope and its superiors
@@ -2818,31 +2861,13 @@ tree
 lookup_name (tree name)
 {
   struct c_binding *b = I_SYMBOL_BINDING (name);
-  struct c_scope *pscope = current_omp_parallel_scope;
 
   if (b == NULL || b->invisible)
     return NULL;
 
-  if (pscope
-      && (TREE_CODE (b->decl) == VAR_DECL
-	  || TREE_CODE (b->decl) == PARM_DECL))
-    {
-      bool did_error = false;
-
-      /* Check that the any default(none) clause is honored.  */
-      if (pscope->omp_default_none
-	  && c_omp_sharing_implicitly_determined (pscope, b))
-	{
-	  error ("%qE not specified in enclosing %<#pragma omp parallel%>",
-		 name);
-	  did_error = true;
-	}
-
-      /* Re-bind the decl to something in scope of the omp parallel.  */
-      if (b->depth < pscope->depth)
-	return c_omp_remap_decl_1 (pscope, b->decl, omp_remap_private ? 0 : -1,
-				   did_error);
-    }
+  if ((TREE_CODE (b->decl) == VAR_DECL || TREE_CODE (b->decl) == PARM_DECL)
+      && current_omp_parallel_scope)
+    b = maybe_remap_for_omp_parallel (current_omp_parallel_scope, b);
 
   return b->decl;
 }
@@ -7862,6 +7887,7 @@ c_begin_omp_parallel (enum omp_clause_de
   current_scope->keep = 1;
   current_scope->omp_parallel_body = 1;
   current_scope->omp_default_none = (def == OMP_CLAUSE_DEFAULT_NONE);
+  current_scope->location = input_location;
   current_omp_parallel_scope = current_scope;
 
   return block;
Index: testsuite/gcc.dg/gomp/parallel-1.c
===================================================================
RCS file: testsuite/gcc.dg/gomp/parallel-1.c
diff -N testsuite/gcc.dg/gomp/parallel-1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/gomp/parallel-1.c	29 Sep 2005 23:02:19 -0000
@@ -0,0 +1,17 @@
+// { dg-do compile }
+
+void foo()
+{
+  int i;
+
+  #pragma omp parallel
+    {
+    #pragma omp parallel
+      {
+      #pragma omp parallel
+        {
+ 	  i++;
+	}
+      }
+    }
+}
Index: testsuite/gcc.dg/gomp/parallel-2.c
===================================================================
RCS file: testsuite/gcc.dg/gomp/parallel-2.c
diff -N testsuite/gcc.dg/gomp/parallel-2.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/gomp/parallel-2.c	29 Sep 2005 23:02:19 -0000
@@ -0,0 +1,17 @@
+// { dg-do compile }
+
+void foo()
+{
+  int i;
+
+  #pragma omp parallel default(none)		// { dg-error "enclosing" }
+    {
+    #pragma omp parallel
+      {
+      #pragma omp parallel default(none)	// { dg-error "enclosing" }
+        {
+ 	  i++;					// { dg-error "not specified" }
+	}
+      }
+    }
+}


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