Attached is an incremental patch to add diagnostic for the in-between
allocator issues, i.e.

On 30.08.23 12:47, Tobias Burnus wrote:
omp_allocator_handle_t uninit;
  int var, var2;
  uninit = omp_low_lat_mem_alloc;
  omp_allocator_handle_t late_declared = omp_low_lat_mem_alloc;
#pragma omp allocate(var) allocator(uninit)
#pragma omp allocate(var) allocator(late_declared)

Further comments, remarks and suggestions to this patch - or the base
patch (v2 in previous email) are highly welcome.

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): omp allocate - improve diagnostic regarding the allocator

gcc/c/ChangeLog:

        * c-parser.cc (c_parser_omp_allocate): Diagnose when allocator
	is declared or modified between the declaration of a list item
	and the 'omp allocate' directive.

gcc/testsuite/ChangeLog:

        * c-c++-common/gomp/allocate-5.c: Fix testcase.
        * c-c++-common/gomp/allocate-12.c: New test.

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index dcc5de7ad93..dfef61da082 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -19445,6 +19445,44 @@ 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 (DECL_SOURCE_LOCATION (allocator) > DECL_SOURCE_LOCATION (var))
+	    {
+	      error_at (OMP_CLAUSE_LOCATION (nl),
+			"allocator variable %qD must be declared before %qD",
+			allocator, var);
+	      inform (DECL_SOURCE_LOCATION (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 (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;
+	     }
+	   }
+	}
       DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("omp allocate"),
 					 build_tree_list (allocator, alignment),
 					 DECL_ATTRIBUTES (var));
diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-5.c b/gcc/testsuite/c-c++-common/gomp/allocate-5.c
index de1efc6832d..2ca4786264f 100644
--- a/gcc/testsuite/c-c++-common/gomp/allocate-5.c
+++ b/gcc/testsuite/c-c++-common/gomp/allocate-5.c
@@ -18,9 +18,9 @@ typedef enum omp_allocator_handle_t
 void
 foo ()
 {
+  omp_allocator_handle_t my_allocator = omp_default_mem_alloc;
   int a, b;
   static int c;
-  omp_allocator_handle_t my_allocator;
 #pragma omp allocate (a)  /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } } */
 #pragma omp allocate (b) allocator(my_allocator)  /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } } */
 #pragma omp allocate(c) align(32)
diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-12.c b/gcc/testsuite/c-c++-common/gomp/allocate-12.c
new file mode 100644
index 00000000000..38836ef5089
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/allocate-12.c
@@ -0,0 +1,43 @@
+/* TODO: enable for C++ once implemented. */
+/* { dg-do compile { target c } } */
+
+typedef enum omp_allocator_handle_t
+{
+  omp_default_mem_alloc = 1,
+  omp_low_lat_mem_alloc = 5,
+  __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+int
+f ()
+{
+  omp_allocator_handle_t my_allocator;
+  int n = 5;  /* { dg-note "declared here" } */
+  my_allocator = omp_default_mem_alloc;  /* { dg-error "allocator variable 'my_allocator' must not be modified between declaration of 'n' and its 'allocate' directive" } */
+  #pragma omp allocate(n) allocator(my_allocator)  /* { dg-note "used here" } */
+  n = 7;
+  return n;
+}
+
+
+int
+g ()
+{
+  int n = 5;  /* { dg-note "declared here" } */
+  omp_allocator_handle_t my_allocator = omp_low_lat_mem_alloc;  /* { dg-note "declared here" } */
+  #pragma omp allocate(n) allocator(my_allocator)  /* { dg-error "allocator variable 'my_allocator' must be declared before 'n'" } */
+  n = 7;
+  return n;
+}
+
+int
+h ()
+{
+  /* my_allocator uninitialized - but only diagnosed in the ME with -Wuninitialized;
+     see gomp/allocate-10.c.  */
+  omp_allocator_handle_t my_allocator;
+  int n = 5;
+  #pragma omp allocate(n) allocator(my_allocator)
+  n = 7;
+  return n;
+}

Reply via email to