Skip to content

Commit 2afcda6

Browse files
committed
[-Wunsafe-buffer-usage] Fix assertion failure in case of BindingDecl
Differential Revision: https://reviews.llvm.org/D158112#inline-1530312
1 parent c730c62 commit 2afcda6

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,10 @@ class FixableGadget : public Gadget {
380380
}
381381
};
382382

383+
static auto toSupportedVariable() {
384+
return to(varDecl());
385+
}
386+
383387
using FixableGadgetList = std::vector<std::unique_ptr<FixableGadget>>;
384388
using WarningGadgetList = std::vector<std::unique_ptr<WarningGadget>>;
385389

@@ -566,7 +570,8 @@ class PointerInitGadget : public FixableGadget {
566570
static Matcher matcher() {
567571
auto PtrInitStmt = declStmt(hasSingleDecl(varDecl(
568572
hasInitializer(ignoringImpCasts(declRefExpr(
569-
hasPointerType()).
573+
hasPointerType(),
574+
toSupportedVariable()).
570575
bind(PointerInitRHSTag)))).
571576
bind(PointerInitLHSTag)));
572577

@@ -616,10 +621,10 @@ class PointerAssignmentGadget : public FixableGadget {
616621
static Matcher matcher() {
617622
auto PtrAssignExpr = binaryOperator(allOf(hasOperatorName("="),
618623
hasRHS(ignoringParenImpCasts(declRefExpr(hasPointerType(),
619-
to(varDecl())).
624+
toSupportedVariable()).
620625
bind(PointerAssignRHSTag))),
621626
hasLHS(declRefExpr(hasPointerType(),
622-
to(varDecl())).
627+
toSupportedVariable()).
623628
bind(PointerAssignLHSTag))));
624629

625630
return stmt(isInUnspecifiedUntypedContext(PtrAssignExpr));
@@ -691,7 +696,8 @@ class ULCArraySubscriptGadget : public FixableGadget {
691696
static Matcher matcher() {
692697
auto ArrayOrPtr = anyOf(hasPointerType(), hasArrayType());
693698
auto BaseIsArrayOrPtrDRE =
694-
hasBase(ignoringParenImpCasts(declRefExpr(ArrayOrPtr)));
699+
hasBase(ignoringParenImpCasts(declRefExpr(ArrayOrPtr,
700+
toSupportedVariable())));
695701
auto Target =
696702
arraySubscriptExpr(BaseIsArrayOrPtrDRE).bind(ULCArraySubscriptTag);
697703

@@ -733,7 +739,8 @@ class UPCStandalonePointerGadget : public FixableGadget {
733739
static Matcher matcher() {
734740
auto ArrayOrPtr = anyOf(hasPointerType(), hasArrayType());
735741
auto target = expr(
736-
ignoringParenImpCasts(declRefExpr(allOf(ArrayOrPtr, to(varDecl()))).bind(DeclRefExprTag)));
742+
ignoringParenImpCasts(declRefExpr(allOf(ArrayOrPtr,
743+
toSupportedVariable())).bind(DeclRefExprTag)));
737744
return stmt(isInUnspecifiedPointerContext(target));
738745
}
739746

@@ -769,7 +776,7 @@ class PointerDereferenceGadget : public FixableGadget {
769776
unaryOperator(
770777
hasOperatorName("*"),
771778
has(expr(ignoringParenImpCasts(
772-
declRefExpr(to(varDecl())).bind(BaseDeclRefExprTag)))))
779+
declRefExpr(toSupportedVariable()).bind(BaseDeclRefExprTag)))))
773780
.bind(OperatorTag);
774781

775782
return expr(isInUnspecifiedLvalueContext(Target));
@@ -809,7 +816,8 @@ class UPCAddressofArraySubscriptGadget : public FixableGadget {
809816
return expr(isInUnspecifiedPointerContext(expr(ignoringImpCasts(
810817
unaryOperator(hasOperatorName("&"),
811818
hasUnaryOperand(arraySubscriptExpr(
812-
hasBase(ignoringParenImpCasts(declRefExpr())))))
819+
hasBase(ignoringParenImpCasts(declRefExpr(
820+
toSupportedVariable()))))))
813821
.bind(UPCAddressofArraySubscriptTag)))));
814822
}
815823

@@ -961,7 +969,8 @@ class UPCPreIncrementGadget : public FixableGadget {
961969
// things right.
962970
return stmt(isInUnspecifiedPointerContext(expr(ignoringImpCasts(
963971
unaryOperator(isPreInc(),
964-
hasUnaryOperand(declRefExpr())
972+
hasUnaryOperand(declRefExpr(
973+
toSupportedVariable()))
965974
).bind(UPCPreIncrementTag)))));
966975
}
967976

@@ -999,7 +1008,8 @@ class DerefSimplePtrArithFixableGadget : public FixableGadget {
9991008
static Matcher matcher() {
10001009
// clang-format off
10011010
auto ThePtr = expr(hasPointerType(),
1002-
ignoringImpCasts(declRefExpr(to(varDecl())).bind(BaseDeclRefExprTag)));
1011+
ignoringImpCasts(declRefExpr(toSupportedVariable()).
1012+
bind(BaseDeclRefExprTag)));
10031013
auto PlusOverPtrAndInteger = expr(anyOf(
10041014
binaryOperator(hasOperatorName("+"), hasLHS(ThePtr),
10051015
hasRHS(integerLiteral().bind(OffsetTag)))
@@ -1106,7 +1116,7 @@ findGadgets(const Decl *D, const UnsafeBufferUsageHandler &Handler,
11061116
// In parallel, match all DeclRefExprs so that to find out
11071117
// whether there are any uncovered by gadgets.
11081118
declRefExpr(anyOf(hasPointerType(), hasArrayType()),
1109-
to(varDecl())).bind("any_dre"),
1119+
to(anyOf(varDecl(), bindingDecl()))).bind("any_dre"),
11101120
// Also match DeclStmts because we'll need them when fixing
11111121
// their underlying VarDecls that otherwise don't have
11121122
// any backreferences to DeclStmts.

clang/test/SemaCXX/warn-unsafe-buffer-usage-debug.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,23 @@ void test_decomp_decl() {
7878
auto [x, y] = a;
7979
x = 9;
8080
}
81+
82+
void test_claim_use_multiple() {
83+
int *a = new int[8]; // expected-warning{{'a' is an unsafe pointer used for buffer access}}
84+
a[6] = 9; // expected-note{{used in buffer access here}}
85+
a++; // expected-note{{used in pointer arithmetic here}} \
86+
// debug-note{{safe buffers debug: failed to produce fixit for 'a' : has an unclaimed use}}
87+
}
88+
89+
struct S
90+
{
91+
int *x;
92+
};
93+
94+
S f() { return S{new int[4]}; }
95+
96+
void test_struct_claim_use() {
97+
auto [x] = f();
98+
x[6] = 8; // expected-warning{{unsafe buffer access}}
99+
x++; // expected-warning{{unsafe pointer arithmetic}}
100+
}

0 commit comments

Comments
 (0)