[clang] [Sema] Fix an out-of-bounds crash when diagnosing bad conversion for a function with a parameter pack. (PR #92721)
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Mon May 27 02:44:42 PDT 2024
https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/92721
>From e2dc2cecee5891b88ff4c2e473220cc9fd36df34 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Sun, 19 May 2024 22:47:14 +0200
Subject: [PATCH 1/2] [Sema] Fix an out-of-bounds crash when diagnosing bad
conversion for a function with a parameter pack.
---
clang/docs/ReleaseNotes.rst | 2 ++
clang/lib/Sema/SemaOverload.cpp | 10 ++++++++--
clang/test/Misc/diag-overload-cand-ranges.cpp | 8 ++++++++
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 825e91876ffce..9fd8661949113 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -629,6 +629,8 @@ Bug Fixes in This Version
- ``__is_array`` and ``__is_bounded_array`` no longer return ``true`` for
zero-sized arrays. Fixes (#GH54705).
+- Fix an out-of-bounds crash when diagnosing bad conversion for a function with a parameter pack.
+
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 0c89fca8d38eb..a9603e63336ac 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11301,8 +11301,14 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand,
Expr *FromExpr = Conv.Bad.FromExpr;
QualType FromTy = Conv.Bad.getFromType();
QualType ToTy = Conv.Bad.getToType();
- SourceRange ToParamRange =
- !isObjectArgument ? Fn->getParamDecl(I)->getSourceRange() : SourceRange();
+ SourceRange ToParamRange;
+ if (!isObjectArgument) {
+ if (I < Fn->getNumParams())
+ ToParamRange = Fn->getParamDecl(I)->getSourceRange();
+ else
+ // parameter pack case.
+ ToParamRange = Fn->parameters().back()->getSourceRange();
+ }
if (FromTy == S.Context.OverloadTy) {
assert(FromExpr && "overload set argument came from implicit argument?");
diff --git a/clang/test/Misc/diag-overload-cand-ranges.cpp b/clang/test/Misc/diag-overload-cand-ranges.cpp
index 080ca484d4b74..06d638d9b719c 100644
--- a/clang/test/Misc/diag-overload-cand-ranges.cpp
+++ b/clang/test/Misc/diag-overload-cand-ranges.cpp
@@ -70,3 +70,11 @@ template <short T> class Type1 {};
template <short T> void Function1(int zz, Type1<T> &x, int ww) {}
void Function() { Function1(33, Type1<-42>(), 66); }
+
+// CHECK: error: no matching function for call to 'b'
+// CHECK: :{[[@LINE+1]]:41-[[@LINE+1]]:45}: note: {{.*}} no known conversion from 'int' to 'ForwardClass' for 3rd argument
+template <class T, class...U> void b(T, U...);
+class ForwardClass;
+void NoCrash() {
+ b<int, int, ForwardClass>(1, 1, 0);
+}
>From 4358b43e283cb13dbe4d32fcce3c68b6da15b12a Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Mon, 27 May 2024 09:58:04 +0200
Subject: [PATCH 2/2] review comments
Diagnose on the first parameter pack.
---
clang/lib/Sema/SemaOverload.cpp | 12 +++++++++---
clang/test/Misc/diag-overload-cand-ranges.cpp | 6 +++++-
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index a9603e63336ac..f9a5032e10c2d 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11305,9 +11305,15 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand,
if (!isObjectArgument) {
if (I < Fn->getNumParams())
ToParamRange = Fn->getParamDecl(I)->getSourceRange();
- else
- // parameter pack case.
- ToParamRange = Fn->parameters().back()->getSourceRange();
+ else {
+ // For the parameter pack case, diagnose on the first pack.
+ for (const auto* ParamDecl : Fn->parameters()) {
+ if (ParamDecl->isParameterPack()) {
+ ToParamRange = ParamDecl->getSourceRange();
+ break;
+ }
+ }
+ }
}
if (FromTy == S.Context.OverloadTy) {
diff --git a/clang/test/Misc/diag-overload-cand-ranges.cpp b/clang/test/Misc/diag-overload-cand-ranges.cpp
index 06d638d9b719c..a70ba0d1b1f77 100644
--- a/clang/test/Misc/diag-overload-cand-ranges.cpp
+++ b/clang/test/Misc/diag-overload-cand-ranges.cpp
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info %s 2>&1 | FileCheck %s --strict-whitespace
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info -std=c++20 %s 2>&1 | FileCheck %s --strict-whitespace
// CHECK: error: no matching function
template <typename T> struct mcdata {
typedef int result_type;
@@ -74,7 +74,11 @@ void Function() { Function1(33, Type1<-42>(), 66); }
// CHECK: error: no matching function for call to 'b'
// CHECK: :{[[@LINE+1]]:41-[[@LINE+1]]:45}: note: {{.*}} no known conversion from 'int' to 'ForwardClass' for 3rd argument
template <class T, class...U> void b(T, U...);
+// CHECK: error: no matching function for call to 'abbreviated_func'
+// CHECK: :{[[@LINE+1]]:23-[[@LINE+1]]:30}: note: {{.*}} no known conversion from 'int' to 'ForwardClass' for 3rd argument
+void abbreviated_func(auto..., auto...); // diagnose on the first parameter
class ForwardClass;
void NoCrash() {
b<int, int, ForwardClass>(1, 1, 0);
+ abbreviated_func<int, int, ForwardClass>(1, 1, 0);
}
More information about the cfe-commits
mailing list