https://github.com/TPPPP72 created 
https://github.com/llvm/llvm-project/pull/216692

When declaring a class template within an OpenMP region, the presence of 
`CapturedDecl` causes `isLocalClass()` checks to fail, preventing the compiler 
from taking the expected error path.

This patch adds `CapturedDecl` traversal in `SemaTemplate` so that the compiler 
properly emits an error and recovers.

Fix #216052 

>From fe7761276f4f97db3814fe076f183ef8c13e9f93 Mon Sep 17 00:00:00 2001
From: Shengxin Pei <[email protected]>
Date: Mon, 17 Aug 2026 18:30:55 +0800
Subject: [PATCH] [clang] Fixed a crash when declaring a member template within
 a local class inside an OpenMP region

---
 clang/docs/ReleaseNotes.md         |  1 +
 clang/lib/Sema/SemaTemplate.cpp    | 11 +++++++++--
 clang/test/SemaOpenMP/gh216052.cpp | 12 ++++++++++++
 3 files changed, 22 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaOpenMP/gh216052.cpp

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 0e40754efd30e..1fa6c5745b850 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -416,6 +416,7 @@ features cannot lower the translation-unit ABI level;
 - Fixed an ICE that occurred when a structured binding pack is expanded 
outside the lambda where it was declared. (#GH214160)
 - Fixed a bug where a stray closing curley brace in an OpenMP/OpenACC pragma 
could cause pragma parsing issues when inside of a member function. (#GH214195)
 - 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)
 
 #### Bug Fixes to Compiler Builtins
 
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index dff681454ae5a..70b8a3c8ddf31 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -8504,10 +8504,17 @@ Sema::CheckTemplateDeclScope(Scope *S, 
TemplateParameterList *TemplateParams) {
     if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Ctx)) {
       // C++ [temp.mem]p2:
       //   A local class shall not have member templates.
-      if (RD->isLocalClass())
+
+      // RD->isLocalClass() fails under OpenMP captured regions; trace outer
+      // context to bypass CapturedDecl.
+      const DeclContext *OutCtx = RD->getDeclContext();
+      while (isa_and_nonnull<CapturedDecl>(OutCtx))
+        OutCtx = OutCtx->getParent();
+
+      if (RD->isLocalClass() || (OutCtx && OutCtx->isFunctionOrMethod()))
         return Diag(TemplateParams->getTemplateLoc(),
                     diag::err_template_inside_local_class)
-          << TemplateParams->getSourceRange();
+               << TemplateParams->getSourceRange();
       else
         return false;
     }
diff --git a/clang/test/SemaOpenMP/gh216052.cpp 
b/clang/test/SemaOpenMP/gh216052.cpp
new file mode 100644
index 0000000000000..f7e53a6589106
--- /dev/null
+++ b/clang/test/SemaOpenMP/gh216052.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fopenmp -fsyntax-only -verify %s
+
+void foo() {
+#pragma omp parallel
+  class O {
+    // expected-error@+1 {{templates cannot be declared inside of a local 
class}}
+    template <class T> class I {
+      void bar(bool b = true);
+    };
+    I<int> bar; // expected-error {{no template named 'I'}}
+  };
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to