-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[Wunsafe-buffer-usage] False positives for & expression indexing constant size array (arr[anything & 0]) #112284
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 1 commit
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 |
|---|---|---|
|
|
@@ -462,8 +462,25 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) { | |
| // bug | ||
| if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < limit) | ||
| return true; | ||
| } | ||
| return false; | ||
| } else if (const auto *BE = dyn_cast<BinaryOperator>(IndexExpr)) { | ||
| if (BE->getOpcode() != BO_And) | ||
| return false; | ||
|
|
||
| const Expr *LHS = BE->getLHS(); | ||
| const Expr *RHS = BE->getRHS(); | ||
|
|
||
| if ((!LHS->isValueDependent() && | ||
|
Contributor
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. if
Contributor
Author
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. The Expr::EvaluateAsInt(...) method assumes the expression it operates on in not value dependent. So, we have to check this before hand to make sure the method does not crash. We can only skip this check if we can be guaranteed the expression is never value dependent. I don't think that is true here. |
||
| LHS->EvaluateAsInt(EVResult, Finder->getASTContext())) || | ||
| (!RHS->isValueDependent() && | ||
| RHS->EvaluateAsInt(EVResult, Finder->getASTContext()))) { | ||
| llvm::APSInt result = EVResult.Val.getInt(); | ||
| if (result.isNonNegative() && result.getLimitedValue() < limit) | ||
| return true; | ||
| } | ||
| return false; | ||
|
|
||
| } else | ||
|
||
| return false; | ||
| } | ||
|
|
||
| AST_MATCHER_P(CallExpr, hasNumArgs, unsigned, Num) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,7 +18,9 @@ void foo2(unsigned idx) { | |
|
|
||
| struct Foo { | ||
| int member_buffer[10]; | ||
| int x; | ||
| }; | ||
|
|
||
| void foo2(Foo& f, unsigned idx) { | ||
| f.member_buffer[idx] = 0; // expected-warning{{unsafe buffer access}} | ||
| } | ||
|
|
@@ -33,6 +35,35 @@ void constant_idx_safe0(unsigned idx) { | |
| buffer[0] = 0; | ||
| } | ||
|
|
||
| int array[10]; // expected-warning {{'array' is an unsafe buffer that does not perform bounds checks}} | ||
|
|
||
| void masked_idx1(unsigned long long idx, Foo f) { | ||
| // Bitwise and operation | ||
| array[idx & 5] = 10; // no warning | ||
| array[idx & 11 & 5] = 3; // no warning | ||
| array[idx & 11] = 20; // expected-note{{used in buffer access here}} | ||
| array[idx &=5]; // expected-note{{used in buffer access here}} | ||
| array[f.x & 5]; | ||
| } | ||
|
|
||
| typedef unsigned long long uint64_t; | ||
| typedef unsigned int uint32_t; | ||
| typedef unsigned char uint8_t; | ||
|
|
||
| void type_conversions(uint64_t idx1, uint32_t idx2, uint8_t idx3) { | ||
| array[(uint32_t)idx1 & 3]; | ||
| array[idx2 & 3]; | ||
| array[idx3 & 3]; | ||
| } | ||
|
|
||
| int array2[5]; // expected-warning {{'array2' is an unsafe buffer that does not perform bounds checks}} | ||
|
|
||
| void masked_idx_safe(unsigned long long idx) { | ||
| array2[6 & 5]; // no warning | ||
| array2[6 & idx & (idx + 1) & 5]; // expected-note{{used in buffer access here}} | ||
| } | ||
|
|
||
|
|
||
|
||
| void constant_idx_unsafe(unsigned idx) { | ||
| int buffer[10]; // expected-warning{{'buffer' is an unsafe buffer that does not perform bounds checks}} | ||
| // expected-note@-1{{change type of 'buffer' to 'std::array' to label it for hardening}} | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.