llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Akash Manna (akash-manna-sky)

<details>
<summary>Changes</summary>

Fixes #<!-- -->223366

`VisitOMPDeclareReductionDecl` passed the substituted reduction type to 
`ActOnOpenMPDeclareReductionType` without checking it, so a failed substitution 
(null type) hit `assert(ParsedType.isUsable())`. `-fms-compatibility` is not 
needed: `typename T::type` with `T = int` crashes too. `declare mapper` had the 
same bug.

Both visitors now return early when the substituted type is null. The error is 
already reported by `SubstType`.

I used AI tools for assistance!


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


5 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+2) 
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+10-6) 
- (modified) clang/test/OpenMP/declare_mapper_messages.cpp (+20) 
- (modified) clang/test/OpenMP/declare_reduction_messages.cpp (+16) 
- (added) clang/test/OpenMP/declare_reduction_ms_compat.cpp (+25) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 7ec126a065ae5..a7683d7532475 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -588,6 +588,8 @@ features cannot lower the translation-unit ABI level;
 - Fixed a crash when an OpenMP `copyprivate` clause names a non-static data 
member that is not private in the
   enclosing context, which is now diagnosed, a data member inside a member 
function template, or a structured
   binding. (#GH217893)
+- Fixed a crash when template argument substitution fails in the type of an 
OpenMP `declare reduction` or
+  `declare mapper` directive. (#GH223366)
 - Fixed an assertion failure when a variable implicitly mapped by an OpenMP 
`target` directive has a class type
   (such as `std::map`) whose mapper lookup instantiates a class template 
specialization. (#GH154704)
 - Fixed a bug where repeated #imports of modular headers in non-modular 
compilation were translated to #pragma clang module import. (#GH216924)
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 5e72f05c863a0..eaa82623eb6b6 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4569,10 +4569,12 @@ Decl 
*TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
       D->getType()->containsUnexpandedParameterPack();
   QualType SubstReductionType;
   if (RequiresInstantiation) {
+    QualType T = SemaRef.SubstType(D->getType(), TemplateArgs, 
D->getLocation(),
+                                   DeclarationName());
+    if (T.isNull())
+      return nullptr;
     SubstReductionType = SemaRef.OpenMP().ActOnOpenMPDeclareReductionType(
-        D->getLocation(),
-        ParsedType::make(SemaRef.SubstType(
-            D->getType(), TemplateArgs, D->getLocation(), DeclarationName())));
+        D->getLocation(), ParsedType::make(T));
   } else {
     SubstReductionType = D->getType();
   }
@@ -4661,10 +4663,12 @@ 
TemplateDeclInstantiator::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
   QualType SubstMapperTy;
   DeclarationName VN = D->getVarName();
   if (RequiresInstantiation) {
+    QualType T =
+        SemaRef.SubstType(D->getType(), TemplateArgs, D->getLocation(), VN);
+    if (T.isNull())
+      return nullptr;
     SubstMapperTy = SemaRef.OpenMP().ActOnOpenMPDeclareMapperType(
-        D->getLocation(),
-        ParsedType::make(SemaRef.SubstType(D->getType(), TemplateArgs,
-                                           D->getLocation(), VN)));
+        D->getLocation(), ParsedType::make(T));
   } else {
     SubstMapperTy = D->getType();
   }
diff --git a/clang/test/OpenMP/declare_mapper_messages.cpp 
b/clang/test/OpenMP/declare_mapper_messages.cpp
index f2101786f6ce0..cf9c339bc44ae 100644
--- a/clang/test/OpenMP/declare_mapper_messages.cpp
+++ b/clang/test/OpenMP/declare_mapper_messages.cpp
@@ -121,3 +121,23 @@ int fun(int arg) {
   }
   return arg;
 }
+
+#if __cplusplus >= 201103L
+namespace GH223366 {
+struct HasType {
+  typedef int type;
+};
+
+template <typename T> using Vec = vec;
+
+template <typename T>
+void f() {
+#pragma omp declare mapper(id : Vec<typename T::type> v) map(v.len) // 
expected-error {{type 'int' cannot be used prior to '::' because it has no 
members}}
+}
+
+void g() {
+  f<HasType>();
+  f<int>(); // expected-note {{in instantiation of function template 
specialization 'GH223366::f<int>' requested here}}
+}
+}
+#endif
diff --git a/clang/test/OpenMP/declare_reduction_messages.cpp 
b/clang/test/OpenMP/declare_reduction_messages.cpp
index f91d952dfa14f..3d49a5d57cdda 100644
--- a/clang/test/OpenMP/declare_reduction_messages.cpp
+++ b/clang/test/OpenMP/declare_reduction_messages.cpp
@@ -167,3 +167,19 @@ struct S
 #pragma omp declare reduction (bar : S<1> : omp_out.foo(omp_in))
 
 #endif
+
+namespace GH223366 {
+struct HasType {
+  typedef int type;
+};
+
+template <typename T>
+void f() {
+#pragma omp declare reduction(red : typename T::type : omp_out += omp_in) // 
expected-error {{type 'int' cannot be used prior to '::' because it has no 
members}}
+}
+
+void g() {
+  f<HasType>();
+  f<int>(); // expected-note {{in instantiation of function template 
specialization 'GH223366::f<int>' requested here}}
+}
+}
diff --git a/clang/test/OpenMP/declare_reduction_ms_compat.cpp 
b/clang/test/OpenMP/declare_reduction_ms_compat.cpp
new file mode 100644
index 0000000000000..96bacfa3f7aec
--- /dev/null
+++ b/clang/test/OpenMP/declare_reduction_ms_compat.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -verify -fopenmp -fms-compatibility %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -fms-compatibility %s
+
+struct foo {};
+struct has_baz {
+  typedef int baz;
+};
+
+template <typename T> struct S : T {
+  virtual void bar() {
+#pragma omp declare reduction(foo : baz : omp_out)
+    // expected-warning@-1 {{use of undeclared identifier 'baz'; unqualified 
lookup into dependent bases of class template 'S' is a Microsoft extension}}
+    // expected-error@-2 {{no type named 'baz' in 'S<foo>'}}
+  }
+};
+
+template <typename T> struct NotInstantiated : T {
+  virtual void bar() {
+#pragma omp declare reduction(foo : baz : omp_out)
+    // expected-warning@-1 {{use of undeclared identifier 'baz'; unqualified 
lookup into dependent bases of class template 'NotInstantiated' is a Microsoft 
extension}}
+  }
+};
+
+S<foo> s; // expected-note {{in instantiation of member function 'S<foo>::bar' 
requested here}}
+S<has_baz> t;

``````````

</details>


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

Reply via email to