[flang-commits] [flang] [flang][OpenMP] Check the context of the declare_simd directive (PR #209318)

via flang-commits flang-commits at lists.llvm.org
Mon Jul 13 14:48:30 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-openmp

@llvm/pr-subscribers-flang-semantics

Author: Carlos Seo (ceseo)

<details>
<summary>Changes</summary>

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

---
Full diff: https://github.com/llvm/llvm-project/pull/209318.diff


4 Files Affected:

- (modified) flang/lib/Semantics/check-omp-structure.cpp (+20) 
- (modified) flang/test/Semantics/OpenMP/declare-simd-empty.f90 (+3) 
- (added) flang/test/Semantics/OpenMP/declare-simd-scope.f90 (+93) 
- (modified) flang/test/Semantics/OpenMP/declare-simd.f90 (+15-9) 


``````````diff
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

``````````

</details>


https://github.com/llvm/llvm-project/pull/209318


More information about the flang-commits mailing list