-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[-Wunsafe-buffer-usage] Ignore constant safe indices in array subscripts #80504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
e075dc3
9f3940e
d6dda2c
e4cf184
cbfde25
752794e
8054350
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -406,6 +406,39 @@ AST_MATCHER(CXXConstructExpr, isSafeSpanTwoParamConstruct) { | |
} | ||
return false; | ||
} | ||
|
||
AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) { | ||
// FIXME: Proper solution: | ||
// - refactor Sema::CheckArrayAccess | ||
// - split safe/OOB/unknown decision logic from diagnostics emitting code | ||
// - e. g. "Try harder to find a NamedDecl to point at in the note." | ||
// already duplicated | ||
// - call both from Sema and from here | ||
|
||
const DeclRefExpr *BaseDRE = | ||
dyn_cast_or_null<DeclRefExpr>(Node.getBase()->IgnoreParenImpCasts()); | ||
if (!BaseDRE) | ||
return false; | ||
if (!BaseDRE->getDecl()) | ||
return false; | ||
const auto *CATy = Finder->getASTContext().getAsConstantArrayType( | ||
BaseDRE->getDecl()->getType()); | ||
if (!CATy) | ||
return false; | ||
const APInt ArrSize = CATy->getSize(); | ||
|
||
if (const auto *IdxLit = dyn_cast<IntegerLiteral>(Node.getIdx())) { | ||
const APInt ArrIdx = IdxLit->getValue(); | ||
// FIXME: ArrIdx.isNegative() we could immediately emit an error as that's a | ||
// bug | ||
if (ArrIdx.isNonNegative() && | ||
ArrIdx.getLimitedValue() < ArrSize.getLimitedValue()) | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
} // namespace clang::ast_matchers | ||
|
||
namespace { | ||
|
@@ -598,16 +631,16 @@ class ArraySubscriptGadget : public WarningGadget { | |
} | ||
|
||
static Matcher matcher() { | ||
// FIXME: What if the index is integer literal 0? Should this be | ||
// a safe gadget in this case? | ||
// clang-format off | ||
// clang-format off | ||
return stmt(arraySubscriptExpr( | ||
hasBase(ignoringParenImpCasts( | ||
anyOf(hasPointerType(), hasArrayType()))), | ||
unless(hasIndex( | ||
anyOf(integerLiteral(equals(0)), arrayInitIndexExpr()) | ||
))) | ||
.bind(ArraySubscrTag)); | ||
unless(anyOf( | ||
isSafeArraySubscript(), | ||
hasIndex( | ||
anyOf(integerLiteral(equals(0)), arrayInitIndexExpr()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is unnecessary now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, it is still necessary - we need to somehow cover:
And that has been defined as out of scope for the warning. I don't feel like calling it "safe" and I'd rather have it visible in the top-level matcher. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So you want to suppress the warning here right? In this case yeah makes sense. It's also somewhat covered by
|
||
) | ||
))).bind(ArraySubscrTag)); | ||
// clang-format on | ||
} | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.