Skip to content

Commit cd26529

Browse files
committed
[-Wunsafe-buffer-usage] Fixits for assignments to array subscript expressions
Let generate fix-its to make assignments' left-hand side of the form `dre[e]` safe if `e` is known to be non-negative. Commit on behalf of jkorous (Jan Korous) Reviewed by: NoQ (Artem Dergachev) Differential revision: https://reviews.llvm.org/D142794
1 parent c8b37e4 commit cd26529

File tree

2 files changed

+29
-5
lines changed

2 files changed

+29
-5
lines changed

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,19 @@ AST_MATCHER_P(CastExpr, castSubExpr, internal::Matcher<Expr>, innerMatcher) {
129129

130130
// Returns a matcher that matches any expression 'e' such that `innerMatcher`
131131
// matches 'e' and 'e' is in an Unspecified Lvalue Context.
132-
static internal::Matcher<Stmt>
133-
isInUnspecifiedLvalueContext(internal::Matcher<Expr> innerMatcher) {
134-
return implicitCastExpr(hasCastKind(CastKind::CK_LValueToRValue),
135-
castSubExpr(innerMatcher));
136-
// FIXME: add assignmentTo context...
132+
static auto isInUnspecifiedLvalueContext(internal::Matcher<Expr> innerMatcher) {
133+
// clang-format off
134+
return
135+
expr(anyOf(
136+
implicitCastExpr(
137+
hasCastKind(CastKind::CK_LValueToRValue),
138+
castSubExpr(innerMatcher)),
139+
binaryOperator(
140+
hasAnyOperatorName("="),
141+
hasLHS(innerMatcher)
142+
)
143+
));
144+
// clang-format off
137145
}
138146
} // namespace clang::ast_matchers
139147

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
2+
3+
// TODO cases where we don't want fixits
4+
5+
// The Fix-It for unsafe operation is trivially empty.
6+
// In order to test that our machinery recognizes that we can test if the variable declaration gets a Fix-It.
7+
// If the operation wasn't handled propertly the declaration won't get Fix-It.
8+
// By testing presence of the declaration Fix-It we indirectly test presence of the trivial Fix-It for its operations.
9+
void test() {
10+
int *p = new int[10];
11+
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span<int> p"
12+
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:12-[[@LINE-2]]:12}:"{"
13+
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:23}:", 10}"
14+
p[5] = 1;
15+
// CHECK-NOT: fix-it:
16+
}

0 commit comments

Comments
 (0)