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
