On Mon, Sep 11, 2023 at 03:21:54PM +0200, Tobias Burnus wrote: > + if (TREE_STATIC (var)) > + { > + if (allocator == NULL_TREE && allocator_loc == UNKNOWN_LOCATION) > + 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))
Has anything checked that in this case allocator is actually INTEGER_CST which fits into shwi? Otherwise tree_to_shwi will ICE. Consider say allocator argument of 329857234985743598347598437598347594835743895743wb or (((unsigned __int128) 0x123456789abcdef0) << 64) Either tree_fits_shwi_p (allocator) check would do it, or perhaps else if (allocator && TREE_CODE (allocator) == INTEGER_CST && wi::to_widest (allocator) > 0 && wi::to_widest (allocator) <= 8) ? > + if (allocator > + && TREE_CODE (allocator) == VAR_DECL > + && c_check_in_current_scope (var)) > + { > + 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; > + } > + } BTW, it doesn't necessarily have to be just the simple case which you catch here, namely that allocator is a VAR_DECL defined after var in current scope. One can have an expression which uses those other vars, say int v; int a = 1; int b[n]; // VLA b[a] = 5; #pragma omp allocate (v) allocator (foo (a, &b[a])) where foo would be some function which returns omp_allocator_handle_t. Or it could be e.g. lambda declared later, etc. I bet we can't catch everything, but perhaps e.g. doing the first diagnostics from within walk_tree might be better. Jakub