llvm-project
46feebb0 - [flang][OpenMP] Gate the allocate clause at OpenMP 5.0 (#213980)

Commit
2 days ago
[flang][OpenMP] Gate the allocate clause at OpenMP 5.0 (#213980) `allocate` is an OpenMP 5.0 clause, but 58 of the 62 directives that allow it declare it as bare `VersionedClause<OMPC_Allocate>`. The default in `DirectiveBase.td` is `min = 1`: ``` class VersionedClause<Clause c, int min = 1, int max = 0x7FFFFFFF> : Versioned<min, max> ``` so those 58 accept the clause at every version. Only four are gated today: `do`, `taskgroup` and `parallel do` at 50, and `scope` at 52. This is reachable in practice because flang defaults to OpenMP 3.1 (`newestFullySupported = 31`, `CompilerInvocation.cpp`). An invocation with no `-fopenmp-version=` lands in the ungated range, semantics accepts the clause, and `ConstructDecomposition` then correctly refuses to decompose it. Lowering consumes the empty result and crashes: ``` $ flang -fc1 -emit-hlfir -fopenmp repro.f90 Segmentation fault ``` In an assertions build it is caught at `Decomposer.cpp:85`: ``` Assertion `!decompose.output.empty() && "Construct decomposition failed"' failed. ``` With the gate, that becomes a diagnostic: ``` error: ALLOCATE clause is not allowed on TARGET TEAMS DISTRIBUTE PARALLEL DO directive in OpenMP v3.1, try -fopenmp-version=50 ``` Reported as #211430. ### Scope This fixes reachability, not the underlying memory error, and should not be read as a complete fix for #211430. Consuming a failed decomposition reads uninitialized memory, which is why the crash is intermittent — measured on a release build at a pinned `-fopenmp-version=31`, 40 trials each: | | segfaults | |---|---| | ASLR on | 25/40 | | ASLR off (`setarch -R`) | 0/40 | Any other clause/directive combination that makes decomposition return empty will hit the same path. Making that path diagnose and bail rather than fall through is a separate change. I also left the gate uniform at 50 rather than tightening per directive. `allocators` is a 5.2 construct, so by the precedent `scope` sets its clause could be 52; that argument applies to several directives here and depends on each one's introduction version, so it seemed better kept out of a mechanical change. ### Tests Nine tests exercised `allocate` through bare `%openmp_flags` (i.e. `-fopenmp` with no version) and so depended on the missing gate. Seven get `-fopenmp-version=50`. The two `allocators` tests get 52, which is what their own `! OpenMP Version 5.2` header comments already claim they are testing. ### Verification | suite | tests | failed | |---|---|---| | `check-flang` | 4808 | 0 | | `mlir/test/Dialect/OpenMP`, `mlir/test/Target/LLVMIR`, `llvm/test/Frontend` | 425 | 0 | | `clang/test/OpenMP` | 1594 | 0 | clang version-checks `allocate` in its own semantic analysis rather than through this table, but it shares `OMP.td`, so I ran it to confirm. --- Parts of this change were written or audited with Claude Code. I have reviewed all of it and take full responsibility for the contribution. See `llvm/docs/AIToolPolicy.md`.
Author
Parents
Loading