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 <[email protected]> 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) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
