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; +}