From 1f6727c2b6f8ac023332289db404c027d3b1e3fb Mon Sep 17 00:00:00 2001 From: Matheus Izvekov Date: Tue, 21 Oct 2025 18:25:07 -0300 Subject: [PATCH] [clang] OpenMP: fix variant template mismatch crash This ammends the fix commited in https://reviews.llvm.org/D109770 / 6cf6fa6ef1c28 Comparing the number of template parameter lists with the number of template parameters is obviously wrong. Even then, the number of parameters being the same doesn't mean the templates are compatible. This change compares if the template parameters are actually equivalent. This fixes the crash, but I am not sure what is the design and intention here, this openmp template support looks too fragile. The added test case still doesn't work, but at least we don't crash now. --- clang/lib/Sema/SemaOpenMP.cpp | 4 +++- .../openmp-begin-declare-variant_template.cpp | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaOpenMP/openmp-begin-declare-variant_template.cpp diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 5b5b1b685e153..6d5cb0fcaea24 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -7246,7 +7246,9 @@ void SemaOpenMP::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( FunctionDecl *UDecl = nullptr; if (IsTemplated && isa(CandidateDecl)) { auto *FTD = cast(CandidateDecl); - if (FTD->getTemplateParameters()->size() == TemplateParamLists.size()) + // FIXME: Should this compare the template parameter lists on all levels? + if (SemaRef.Context.isSameTemplateParameterList( + FTD->getTemplateParameters(), TemplateParamLists.back())) UDecl = FTD->getTemplatedDecl(); } else if (!IsTemplated) UDecl = dyn_cast(CandidateDecl); diff --git a/clang/test/SemaOpenMP/openmp-begin-declare-variant_template.cpp b/clang/test/SemaOpenMP/openmp-begin-declare-variant_template.cpp new file mode 100644 index 0000000000000..ded8f58253540 --- /dev/null +++ b/clang/test/SemaOpenMP/openmp-begin-declare-variant_template.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple x86_64 -fopenmp -verify %s + +// FIXME: Is this supposed to work? + +#pragma omp begin declare variant match(implementation={extension(allow_templates)}) +template void f(T) {} +// expected-note@-1 {{explicit instantiation refers here}} +#pragma end +template struct A {}; +template A f() = delete; +template void f(float); +// expected-error@-1 {{explicit instantiation of undefined function template 'f'}}