Seems as if I missed a 'git add -u' yesterday evening + missed this when
rechecking this morning.

Now included as separate patch :-/
Unless there are comments, I intent to commit it very soon.

Namely, the actual c-parse.cc update was missing and only the updated
tests were included. In particular missing:

On 12.09.23 09:04, Tobias Burnus wrote:
+          error_at (OMP_CLAUSE_LOCATION (nl),
+                    "allocator variable %qD must be declared before
%qD",
+                    allocator, var);
...
...
I bet we can't catch everything, but perhaps e.g. doing the first
diagnostics from within walk_tree might be better.

Done now.

(Or only via the attach patch.)

Tobias
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
OpenMP (C only): For 'omp allocate', really walk tree for 'alloctor' check

Walk expression tree of the 'allocator' clause of 'omp allocate' to
detect more cases where the allocator expression depends on code between
a variable declaration and its associated '#pragma omp allocate'.

This commit was supposed to be part of
  r14-3863-g35f498d8dfc8e579eaba2ff2d2b96769c632fd58
  OpenMP (C only): omp allocate - extend parsing support, improve diagnostic
which also contains the associated testcase changes (oops!).

gcc/c/ChangeLog:

	* c-parser.cc (struct c_omp_loc_tree): New.
	(c_check_omp_allocate_allocator_r): New; checking moved from ...
	(c_parser_omp_allocate): ... here. Call it via walk_tree.

 gcc/c/c-parser.cc | 102 ++++++++++++++++++++++++++++++++----------------------
 1 file changed, 61 insertions(+), 41 deletions(-)

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 643ec02706b..b9a1b75ca43 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -19343,6 +19343,61 @@ c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
   return stmt;
 }
 
+struct c_omp_loc_tree
+{
+  location_t loc;
+  tree var;
+};
+
+/* Check whether the expression used in the allocator clause is declared or
+   modified between the variable declaration and its allocate directive.  */
+static tree
+c_check_omp_allocate_allocator_r (tree *tp, int *, void *data)
+{
+  tree var = ((struct c_omp_loc_tree *) data)->var;
+  location_t loc = ((struct c_omp_loc_tree *) data)->loc;
+  if (TREE_CODE (*tp) == VAR_DECL && c_check_in_current_scope (*tp))
+    {
+      if (linemap_location_before_p (line_table, DECL_SOURCE_LOCATION (var),
+				     DECL_SOURCE_LOCATION (*tp)))
+	{
+	  error_at (loc, "variable %qD used in the %<allocator%> clause must "
+			 "be declared before %qD", *tp, var);
+	  inform (DECL_SOURCE_LOCATION (*tp), "declared here");
+	  inform (DECL_SOURCE_LOCATION (var),
+		  "to be allocated variable declared here");
+	  return *tp;
+	}
+      else
+	{
+	  gcc_assert (cur_stmt_list
+		      && TREE_CODE (cur_stmt_list) == STATEMENT_LIST);
+
+	  tree_stmt_iterator l = tsi_last (cur_stmt_list);
+	  while (!tsi_end_p (l))
+	    {
+	      if (linemap_location_before_p (line_table, EXPR_LOCATION (*l),
+					     DECL_SOURCE_LOCATION (var)))
+		  break;
+	      if (TREE_CODE (*l) == MODIFY_EXPR
+		  && TREE_OPERAND (*l, 0) == *tp)
+		{
+		  error_at (loc,
+			    "variable %qD used in the %<allocator%> clause "
+			    "must not be modified between declaration of %qD "
+			    "and its %<allocate%> directive", *tp, var);
+		  inform (EXPR_LOCATION (*l), "modified here");
+		  inform (DECL_SOURCE_LOCATION (var),
+			  "to be allocated variable declared here");
+		  return *tp;
+		}
+	      --l;
+	    }
+	}
+    }
+  return NULL_TREE;
+}
+
 /* OpenMP 5.x:
    # pragma omp allocate (list)  clauses
 
@@ -19465,8 +19520,8 @@ c_parser_omp_allocate (c_parser *parser)
 	    error_at (loc, "%<allocator%> clause required for "
 			   "static variable %qD", var);
 	  else if (allocator
-		   && (tree_int_cst_sgn (allocator) != 1
-		       || tree_to_shwi (allocator) > 8))
+		   && (wi::to_widest (allocator) < 1
+		       || wi::to_widest (allocator) > 8))
 	    /* 8 = largest predefined memory allocator. */
 	    error_at (allocator_loc,
 		      "%<allocator%> clause requires a predefined allocator as "
@@ -19477,46 +19532,11 @@ c_parser_omp_allocate (c_parser *parser)
 		      "%qD not yet supported", var);
 	  continue;
 	}
-      if (allocator
-	  && TREE_CODE (allocator) == VAR_DECL
-	  && c_check_in_current_scope (var))
+      if (allocator)
 	{
-	  if (linemap_location_before_p (line_table, DECL_SOURCE_LOCATION (var),
-					 DECL_SOURCE_LOCATION (allocator)))
-	    {
-	      error_at (OMP_CLAUSE_LOCATION (nl),
-			"allocator variable %qD must be declared before %qD",
-			allocator, var);
-	      inform (DECL_SOURCE_LOCATION (allocator),
-		      "allocator declared here");
-	      inform (DECL_SOURCE_LOCATION (var), "declared here");
-	    }
-	  else
-	   {
-	     gcc_assert (cur_stmt_list
-			 && TREE_CODE (cur_stmt_list) == STATEMENT_LIST);
-	     tree_stmt_iterator l = tsi_last (cur_stmt_list);
-	     while (!tsi_end_p (l))
-	       {
-		 if (linemap_location_before_p (line_table, EXPR_LOCATION (*l),
-						DECL_SOURCE_LOCATION (var)))
-		   break;
-		 if (TREE_CODE (*l) == MODIFY_EXPR
-		     && TREE_OPERAND (*l, 0) == allocator)
-		   {
-		     error_at (EXPR_LOCATION (*l),
-			       "allocator variable %qD, used in the "
-			       "%<allocate%> directive for %qD, must not be "
-			       "modified between declaration of %qD and its "
-			       "%<allocate%> directive",
-			       allocator, var, var);
-		     inform (DECL_SOURCE_LOCATION (var), "declared here");
-		     inform (OMP_CLAUSE_LOCATION (nl), "used here");
-		     break;
-		  }
-		--l;
-	     }
-	   }
+	  struct c_omp_loc_tree data
+	    = {EXPR_LOC_OR_LOC (allocator, OMP_CLAUSE_LOCATION (nl)), var};
+	  walk_tree (&allocator, c_check_omp_allocate_allocator_r, &data, NULL);
 	}
       DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("omp allocate"),
 					 build_tree_list (allocator, alignment),

Reply via email to