llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Shengxin Pei (TPPPP72)

<details>
<summary>Changes</summary>

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 

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


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+1) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+9-2) 
- (added) clang/test/SemaOpenMP/gh216052.cpp (+12) 


``````````diff
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'}}
+  };
+}

``````````

</details>


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

Reply via email to