https://github.com/ziqingluo-90 updated https://github.com/llvm/llvm-project/pull/102953
>From d6c860de3facc37f27b17a26a01e48bc02b4659b Mon Sep 17 00:00:00 2001 From: ziqingluo-90 <ziqing_...@apple.com> Date: Mon, 12 Aug 2024 11:57:17 -0700 Subject: [PATCH] [-Wunsafe-buffer-usage] Fix a bug in the ASTMatcher for span constructors `QualType::isConstantArrayType()` checks canonical type. So a following cast should be applied to canonical type as well. And, a better option is to use `ASTContext::getAsArrayType()`. ``` if (Ty->isConstantArrayType()) cast<ConstantArrayType>(Ty); // this is incorrect if (auto *CAT = Context.getAsConstantArrayType(Ty)) ... // this is good ``` --- clang/lib/Analysis/UnsafeBufferUsage.cpp | 14 +++++++------- ...fe-buffer-usage-in-container-span-construct.cpp | 3 +++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp index 866222380974b6..db7ec5741f91c4 100644 --- a/clang/lib/Analysis/UnsafeBufferUsage.cpp +++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp @@ -402,9 +402,9 @@ AST_MATCHER(CXXConstructExpr, isSafeSpanTwoParamConstruct) { QualType Arg0Ty = Arg0->IgnoreImplicit()->getType(); - if (Arg0Ty->isConstantArrayType()) { - const APSInt ConstArrSize = - APSInt(cast<ConstantArrayType>(Arg0Ty)->getSize()); + if (auto *ConstArrTy = + Finder->getASTContext().getAsConstantArrayType(Arg0Ty)) { + const APSInt ConstArrSize = APSInt(ConstArrTy->getSize()); // Check form 4: return Arg1CV && APSInt::compareValues(ConstArrSize, *Arg1CV) == 0; @@ -2659,7 +2659,7 @@ static FixItList fixVarDeclWithArray(const VarDecl *D, const ASTContext &Ctx, // Note: the code below expects the declaration to not use any type sugar like // typedef. - if (auto CAT = dyn_cast<clang::ConstantArrayType>(D->getType())) { + if (auto CAT = Ctx.getAsConstantArrayType(D->getType())) { const QualType &ArrayEltT = CAT->getElementType(); assert(!ArrayEltT.isNull() && "Trying to fix a non-array type variable!"); // FIXME: support multi-dimensional arrays @@ -2792,9 +2792,9 @@ fixVariable(const VarDecl *VD, FixitStrategy::Kind K, return {}; } case FixitStrategy::Kind::Array: { - if (VD->isLocalVarDecl() && - isa<clang::ConstantArrayType>(VD->getType().getCanonicalType())) - return fixVariableWithArray(VD, Tracker, Ctx, Handler); + if (VD->isLocalVarDecl()) + if (auto CAT = Ctx.getAsConstantArrayType(VD->getType())) + return fixVariableWithArray(VD, Tracker, Ctx, Handler); DEBUG_NOTE_DECL_FAIL(VD, " : not a local const-size array"); return {}; diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-in-container-span-construct.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-in-container-span-construct.cpp index a1ddc384e0d9b8..e97511593bbd81 100644 --- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-in-container-span-construct.cpp +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-in-container-span-construct.cpp @@ -79,6 +79,8 @@ namespace construct_wt_ptr_size { unsigned Y = 10; std::span<int> S = std::span{&X, 1}; // no-warning int Arr[10]; + typedef int TenInts_t[10]; + TenInts_t Arr2; S = std::span{&X, 2}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} S = std::span{new int[10], 10}; // no-warning @@ -90,6 +92,7 @@ namespace construct_wt_ptr_size { S = std::span{new int[10], 9}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} // not smart enough to tell its safe S = std::span{new int[10], Y}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} // not smart enough to tell its safe S = std::span{Arr, 10}; // no-warning + S = std::span{Arr2, 10}; // no-warning S = std::span{Arr, Y}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} // not smart enough to tell its safe S = std::span{p, 0}; // no-warning } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits