[flang-commits] [flang] [flang][OpenMP] Check the context of the declare_simd directive (PR #209318)
Carlos Seo via flang-commits
flang-commits at lists.llvm.org
Mon Jul 13 14:47:56 PDT 2026
https://github.com/ceseo created https://github.com/llvm/llvm-project/pull/209318
OpenMP 6.0, 9.8 "declare_simd Directive", restricts the placement of the directive:
Any declare_simd directive must appear in the specification part of a
subroutine subprogram, function subprogram, or interface body to which
it applies.
Flang did not enforce this, and accepted the directive in the specification part of a module, submodule, main program or block data.
Note: the restriction requiring the argument to name the procedure to which the directive applies is not implemented here.
Fixes #205478
>From a69cf463e14a139a86beb1cb21f131870a154923 Mon Sep 17 00:00:00 2001
From: Carlos Seo <carlos.seo at linaro.org>
Date: Mon, 13 Jul 2026 18:29:22 -0300
Subject: [PATCH] [flang][OpenMP] Check the context of the declare_simd
directive
OpenMP 6.0, 9.8 "declare_simd Directive", restricts the placement of the
directive:
Any declare_simd directive must appear in the specification part of a
subroutine subprogram, function subprogram, or interface body to which
it applies.
Flang did not enforce this, and accepted the directive in the
specification part of a module, submodule, main program or block data.
Note: the restriction requiring the argument to name the procedure to which the
directive applies is not implemented here.
Fixes #205478
---
flang/lib/Semantics/check-omp-structure.cpp | 20 ++++
.../Semantics/OpenMP/declare-simd-empty.f90 | 3 +
.../Semantics/OpenMP/declare-simd-scope.f90 | 93 +++++++++++++++++++
flang/test/Semantics/OpenMP/declare-simd.f90 | 24 +++--
4 files changed, 131 insertions(+), 9 deletions(-)
create mode 100644 flang/test/Semantics/OpenMP/declare-simd-scope.f90
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 68d7a166be0fb..4a418b8c79a27 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1928,9 +1928,29 @@ void OmpStructureChecker::Leave(const parser::OmpThreadprivateDirective &x) {
void OmpStructureChecker::Enter(const parser::OmpDeclareSimdDirective &x) {
const parser::OmpDirectiveName &dirName{x.v.DirName()};
+ unsigned version{context_.langOptions().OpenMPVersion};
+
const Scope &containingScope = context_.FindScope(dirName.source);
const Scope &progUnitScope = GetProgramUnitContaining(containingScope);
+ // OpenMP 6.0, 9.8 declare_simd Directive, Fortran restriction:
+ // "Any declare_simd directive must appear in the specification part of a
+ // subroutine subprogram, function subprogram, or interface body to which it
+ // applies."
+ // An interface body has a Subprogram scope as well, so checking the scope
+ // kind is sufficient to accept the three allowed contexts, while rejecting
+ // modules, main programs and block data. A BLOCK construct has a scope of
+ // its own, which excludes its specification part from that of the enclosing
+ // subprogram. Placing the directive in an execution part is diagnosed by the
+ // parser.
+ if (GetProgramUnitOrBlockConstructContaining(containingScope).kind() !=
+ Scope::Kind::Subprogram) {
+ context_.Say(dirName.source,
+ "%s directive must appear in the specification part of a subroutine subprogram, function subprogram, or interface body"_err_en_US,
+ GetUpperName(dirName.v, version));
+ return;
+ }
+
// A DECLARE SIMD directive may legally appear in an interface body, but it
// applies to the external procedure being declared rather than to any
// definition in this compilation. Flang does not propagate the directive to
diff --git a/flang/test/Semantics/OpenMP/declare-simd-empty.f90 b/flang/test/Semantics/OpenMP/declare-simd-empty.f90
index b61fb53730a23..11aaa8ffc54f0 100644
--- a/flang/test/Semantics/OpenMP/declare-simd-empty.f90
+++ b/flang/test/Semantics/OpenMP/declare-simd-empty.f90
@@ -1,6 +1,9 @@
! RUN: %python %S/../test_errors.py %s %flang -fopenmp
! Test the source code starting with omp syntax
+! The directive is in the specification part of a main program, which is not a
+! subroutine subprogram, function subprogram, or interface body.
+!ERROR: DECLARE SIMD directive must appear in the specification part of a subroutine subprogram, function subprogram, or interface body
!$omp declare simd
integer :: x
end
diff --git a/flang/test/Semantics/OpenMP/declare-simd-scope.f90 b/flang/test/Semantics/OpenMP/declare-simd-scope.f90
new file mode 100644
index 0000000000000..64870cd79f42c
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/declare-simd-scope.f90
@@ -0,0 +1,93 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=60
+
+! OpenMP 6.0, 9.8 declare_simd Directive, Fortran restriction:
+! "Any declare_simd directive must appear in the specification part of a
+! subroutine subprogram, function subprogram, or interface body to which it
+! applies."
+
+module m
+ procedure() :: ext
+
+!ERROR: DECLARE_SIMD directive must appear in the specification part of a subroutine subprogram, function subprogram, or interface body
+ !$omp declare simd
+
+!ERROR: DECLARE_SIMD directive must appear in the specification part of a subroutine subprogram, function subprogram, or interface body
+ !$omp declare_simd(ext)
+
+contains
+
+ ! Ok: module subprogram.
+ subroutine mod_sub(i)
+ integer :: i
+ !$omp declare simd(mod_sub) linear(i:1)
+ i = i + 1
+ end subroutine
+
+ ! Ok: module function.
+ integer function mod_fun(i)
+ integer :: i
+ !$omp declare_simd
+ mod_fun = i
+ end function
+end module
+
+submodule (m) sm
+!ERROR: DECLARE_SIMD directive must appear in the specification part of a subroutine subprogram, function subprogram, or interface body
+ !$omp declare simd
+end submodule
+
+block data bd
+ integer :: x
+ common /blk/ x
+!ERROR: DECLARE_SIMD directive must appear in the specification part of a subroutine subprogram, function subprogram, or interface body
+ !$omp declare simd
+ data x /0/
+end block data
+
+program main
+!ERROR: DECLARE_SIMD directive must appear in the specification part of a subroutine subprogram, function subprogram, or interface body
+ !$omp declare simd
+end program
+
+! The specification part of a BLOCK construct is not the specification part of
+! the enclosing subprogram.
+subroutine in_block(i)
+ integer :: i
+ block
+!ERROR: DECLARE_SIMD directive must appear in the specification part of a subroutine subprogram, function subprogram, or interface body
+ !$omp declare simd
+ i = i + 1
+ end block
+end subroutine
+
+! Ok: external subroutine.
+subroutine ext_sub(i)
+ integer :: i
+ !$omp declare simd(ext_sub) linear(i:1)
+ i = i + 1
+end subroutine
+
+! Ok: external function, with an internal subprogram.
+integer function ext_fun(i)
+ integer :: i
+ !$omp declare simd(ext_fun)
+ ext_fun = inner(i)
+contains
+ ! Ok: internal subprogram.
+ integer function inner(j)
+ integer :: j
+ !$omp declare simd(inner) linear(j:1)
+ inner = j
+ end function
+end function
+
+! Ok: interface body (the directive is ignored, hence the warning).
+subroutine has_interface
+ interface
+ subroutine iface_sub(i)
+!WARNING: 'DECLARE SIMD' directive in an interface body has no effect [-Wopenmp-usage]
+ !$omp declare simd(iface_sub) linear(i:1)
+ integer :: i
+ end subroutine
+ end interface
+end subroutine
diff --git a/flang/test/Semantics/OpenMP/declare-simd.f90 b/flang/test/Semantics/OpenMP/declare-simd.f90
index bb259b8722ca2..2e98f79dbe73b 100644
--- a/flang/test/Semantics/OpenMP/declare-simd.f90
+++ b/flang/test/Semantics/OpenMP/declare-simd.f90
@@ -2,26 +2,32 @@
module m
-!ERROR: The name 'x' should refer to a procedure
-!$omp declare_simd(x)
-
-!ERROR: DECLARE_SIMD directive should have at most one argument
-!$omp declare_simd(f00, f01)
+integer :: x
-!ERROR: The argument to the DECLARE_SIMD directive should be a procedure name
-!$omp declare_simd(v : integer)
+! A DECLARE_SIMD directive cannot appear in the specification part of a module.
+!ERROR: DECLARE_SIMD directive must appear in the specification part of a subroutine subprogram, function subprogram, or interface body
+!$omp declare_simd(f00)
contains
subroutine f00
+!ERROR: The name 'x' should refer to a procedure
+!$omp declare_simd(x)
end
subroutine f01
+!ERROR: DECLARE_SIMD directive should have at most one argument
+!$omp declare_simd(f00, f01)
+end
+
+subroutine f02
+!ERROR: The argument to the DECLARE_SIMD directive should be a procedure name
+!$omp declare_simd(v : integer)
end
-integer function f02
+integer function f03
!Ok, expect no diagnostics
-!$omp declare_simd(f02)
+!$omp declare_simd(f03)
end
end module
More information about the flang-commits
mailing list