[clang] 0d18bb6 - [Clang][OpenMP] Fixed an assertion when `#pragma omp declare simd` or `#pragma omp declare variant` is followed by another OpenMP declarative directive containing a qualified identifier (#217875)

via cfe-commits cfe-commits at lists.llvm.org
Sat Aug 22 06:35:17 PDT 2026


Author: Shengxin Pei
Date: 2026-08-22T21:35:12+08:00
New Revision: 0d18bb67d106cdf1e2c9e114ac1b67167a233b6c

URL: https://github.com/llvm/llvm-project/commit/0d18bb67d106cdf1e2c9e114ac1b67167a233b6c
DIFF: https://github.com/llvm/llvm-project/commit/0d18bb67d106cdf1e2c9e114ac1b67167a233b6c.diff

LOG: [Clang][OpenMP] Fixed an assertion when `#pragma omp declare simd` or `#pragma omp declare variant` is followed by another OpenMP declarative directive containing a qualified identifier (#217875)

For code
```cpp
void foo();

#pragma omp declare simd
#pragma omp declare target to(foo)
```
Clang currently accepts this without rejection. The underlying cause is
that OpenMP pragma parsing for directives like `declare target to(...)`
performs name lookup without advancing the source location to create a
new declaration. As a result, the parser fetches the existing Decl of
foo and passes it up to declare simd, silently bypassing Sema
diagnostics.

https://godbolt.org/z/szPne5n45

---

However, when using a qualified name in a namespace:
```cpp
namespace N { void foo(); }

#pragma omp declare simd
#pragma omp declare target to(N::foo)
```
This inherently invalid syntax causes `ActOnReenterFunctionContext` to
an assertion failure because the `DeclContext` of the looked-up `N::foo`
does not match the parser's current lexical context
(`TranslationUnitDecl`).

---

This patch adds a source location check in the parser for declare simd
and declare variant to verify whether the returned Decl is a newly
parsed declaration at the current position. If no new declaration was
created, the parser intercepts it directly and emits
`err_omp_decl_in_declare_simd_variant`. Newly parsed declarations (even
non-function ones like int a;) are still passed through to preserve
existing Sema diagnostics.

Fixed #217204

---------

Co-authored-by: Alexey Bataev <a.bataev at outlook.com>

Added: 
    clang/test/SemaOpenMP/gh217204.cpp

Modified: 
    clang/docs/ReleaseNotes.md
    clang/lib/Parse/ParseOpenMP.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 3c6694f510952..df8479a924771 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -438,6 +438,7 @@ features cannot lower the translation-unit ABI level;
 - Fixed a bug where preprocessor directives following comments were not correctly recognized when using -C. (#GH48361)
 - Fixed a crash when declaring a member template within a local class inside an OpenMP region. (#GH216052)
 - Fixed a bug where repeated #imports of modular headers in non-modular compilation were translated to #pragma clang module import. (#GH216924)
+- Fixed an assertion when `#pragma omp declare simd` or `#pragma omp declare variant` is followed by another OpenMP declarative directive containing a qualified identifier. (#GH217204)
 
 #### Bug Fixes to Compiler Builtins
 

diff  --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 30b6c64e69f4c..b460e9c524cb2 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2214,6 +2214,17 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
           << (DKind == OMPD_declare_simd ? 0 : 1);
       return DeclGroupPtrTy();
     }
+
+    DeclGroupRef DG = Ptr.get();
+    SourceManager &SM = PP.getSourceManager();
+    if (llvm::none_of(DG, [&](const Decl *D) {
+          return SM.isBeforeInTranslationUnit(Loc, D->getBeginLoc());
+        })) {
+      Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
+          << (DKind == OMPD_declare_simd ? 0 : 1);
+      return DeclGroupPtrTy();
+    }
+
     if (DKind == OMPD_declare_simd)
       return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
     assert(DKind == OMPD_declare_variant &&

diff  --git a/clang/test/SemaOpenMP/gh217204.cpp b/clang/test/SemaOpenMP/gh217204.cpp
new file mode 100644
index 0000000000000..4063f38f85a0d
--- /dev/null
+++ b/clang/test/SemaOpenMP/gh217204.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fopenmp -fsyntax-only -verify %s
+
+namespace N {
+  void foo();
+}
+
+#pragma omp declare simd // expected-error {{function declaration is expected after 'declare simd' directive}}
+#pragma omp declare target to(N::foo)
+
+#pragma omp declare variant // expected-error {{function declaration is expected after 'declare variant' directive}}
+#pragma omp declare target to(N::foo)


        


More information about the cfe-commits mailing list