Skip to content

Commit 9aa3b53

Browse files
authored
[-Wunsafe-buffer-usage] Fix a small bug recently found (#102953)
`QualType::isConstantArrayType()` checks canonical type. So a following cast should be applied to canonical type as well: ``` if (Ty->isConstantArrayType()) cast<ConstantArrayType>(Ty.getCanonicalType()); // cast<ConstantArrayType>(Ty) is incorrect ```
1 parent 3dea42f commit 9aa3b53

File tree

2 files changed

+10
-7
lines changed

2 files changed

+10
-7
lines changed

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -402,9 +402,9 @@ AST_MATCHER(CXXConstructExpr, isSafeSpanTwoParamConstruct) {
402402

403403
QualType Arg0Ty = Arg0->IgnoreImplicit()->getType();
404404

405-
if (Arg0Ty->isConstantArrayType()) {
406-
const APSInt ConstArrSize =
407-
APSInt(cast<ConstantArrayType>(Arg0Ty)->getSize());
405+
if (auto *ConstArrTy =
406+
Finder->getASTContext().getAsConstantArrayType(Arg0Ty)) {
407+
const APSInt ConstArrSize = APSInt(ConstArrTy->getSize());
408408

409409
// Check form 4:
410410
return Arg1CV && APSInt::compareValues(ConstArrSize, *Arg1CV) == 0;
@@ -2664,7 +2664,7 @@ static FixItList fixVarDeclWithArray(const VarDecl *D, const ASTContext &Ctx,
26642664

26652665
// Note: the code below expects the declaration to not use any type sugar like
26662666
// typedef.
2667-
if (auto CAT = dyn_cast<clang::ConstantArrayType>(D->getType())) {
2667+
if (auto CAT = Ctx.getAsConstantArrayType(D->getType())) {
26682668
const QualType &ArrayEltT = CAT->getElementType();
26692669
assert(!ArrayEltT.isNull() && "Trying to fix a non-array type variable!");
26702670
// FIXME: support multi-dimensional arrays
@@ -2797,9 +2797,9 @@ fixVariable(const VarDecl *VD, FixitStrategy::Kind K,
27972797
return {};
27982798
}
27992799
case FixitStrategy::Kind::Array: {
2800-
if (VD->isLocalVarDecl() &&
2801-
isa<clang::ConstantArrayType>(VD->getType().getCanonicalType()))
2802-
return fixVariableWithArray(VD, Tracker, Ctx, Handler);
2800+
if (VD->isLocalVarDecl())
2801+
if (auto CAT = Ctx.getAsConstantArrayType(VD->getType()))
2802+
return fixVariableWithArray(VD, Tracker, Ctx, Handler);
28032803

28042804
DEBUG_NOTE_DECL_FAIL(VD, " : not a local const-size array");
28052805
return {};

clang/test/SemaCXX/warn-unsafe-buffer-usage-in-container-span-construct.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ namespace construct_wt_ptr_size {
7979
unsigned Y = 10;
8080
std::span<int> S = std::span{&X, 1}; // no-warning
8181
int Arr[10];
82+
typedef int TenInts_t[10];
83+
TenInts_t Arr2;
8284

8385
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}}
8486
S = std::span{new int[10], 10}; // no-warning
@@ -90,6 +92,7 @@ namespace construct_wt_ptr_size {
9092
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
9193
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
9294
S = std::span{Arr, 10}; // no-warning
95+
S = std::span{Arr2, 10}; // no-warning
9396
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
9497
S = std::span{p, 0}; // no-warning
9598
}

0 commit comments

Comments
 (0)