Skip to content

Commit 95180e1

Browse files
committed
[clang][Sema] Resolving Panic Caused by Inconsistent Arguments in Variadic Template Variables
When template variables are variadic, sema may panic, potentially leading to a situation where the number of function variables exceeds the number of template variables. The sema compares the template signature and function signature parameters one by one, which can trigger an assertion error. This PR, when encountering variadic templates, avoids comparing the template signature and function signature parameters one by one. issue: #70191
1 parent 5dd1fc7 commit 95180e1

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,9 @@ Static Analyzer
10691069
`#65888 <https://github.com/llvm/llvm-project/pull/65888>`_, and
10701070
`#65887 <https://github.com/llvm/llvm-project/pull/65887>`_
10711071

1072+
- Resolving Inconsistent Arguments Panic in Variadic Template Variables.
1073+
(`#70280: <https://github.com/llvm/llvm-project/pull/70280>`_).
1074+
10721075
.. _release-notes-sanitizers:
10731076

10741077
Sanitizers

clang/lib/Sema/SemaOverload.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11092,6 +11092,14 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand,
1109211092
I--;
1109311093
}
1109411094

11095+
bool isVariadic = false;
11096+
for (unsigned N = 0; N < Fn->getNumParams(); N++) {
11097+
if (Fn->getParamDecl(N)->isParameterPack()) {
11098+
isVariadic = true;
11099+
break;
11100+
}
11101+
}
11102+
1109511103
std::string FnDesc;
1109611104
std::pair<OverloadCandidateKind, OverloadCandidateSelect> FnKindPair =
1109711105
ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, Cand->getRewriteKind(),
@@ -11100,8 +11108,9 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand,
1110011108
Expr *FromExpr = Conv.Bad.FromExpr;
1110111109
QualType FromTy = Conv.Bad.getFromType();
1110211110
QualType ToTy = Conv.Bad.getToType();
11103-
SourceRange ToParamRange =
11104-
!isObjectArgument ? Fn->getParamDecl(I)->getSourceRange() : SourceRange();
11111+
SourceRange ToParamRange = !isObjectArgument && !isVariadic
11112+
? Fn->getParamDecl(I)->getSourceRange()
11113+
: SourceRange();
1110511114

1110611115
if (FromTy == S.Context.OverloadTy) {
1110711116
assert(FromExpr && "overload set argument came from implicit argument?");

clang/test/SemaCXX/GH70280.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s
2+
3+
namespace PR70280 {
4+
typedef a; // expected-error {{a type specifier is required for all declarations}}
5+
using b = char*;
6+
template <typename... c> void d(c...) = d<b, a>(0, ""); // expected-error {{no matching function for call to 'd'}}
7+
// expected-error@-1 {{illegal initializer (only variables can be initialized)}}
8+
// expected-note@-2 {{candidate function template not viable: no known conversion from 'const char[1]' to 'a' (aka 'int') for 2nd argument}}
9+
}

0 commit comments

Comments
 (0)