diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp index 41820c80da6b4..2c36d78e60c89 100644 --- a/clang/lib/Analysis/UnsafeBufferUsage.cpp +++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp @@ -380,6 +380,10 @@ class FixableGadget : public Gadget { } }; +static auto toSupportedVariable() { + return to(varDecl()); +} + using FixableGadgetList = std::vector>; using WarningGadgetList = std::vector>; @@ -566,7 +570,8 @@ class PointerInitGadget : public FixableGadget { static Matcher matcher() { auto PtrInitStmt = declStmt(hasSingleDecl(varDecl( hasInitializer(ignoringImpCasts(declRefExpr( - hasPointerType()). + hasPointerType(), + toSupportedVariable()). bind(PointerInitRHSTag)))). bind(PointerInitLHSTag))); @@ -616,10 +621,10 @@ class PointerAssignmentGadget : public FixableGadget { static Matcher matcher() { auto PtrAssignExpr = binaryOperator(allOf(hasOperatorName("="), hasRHS(ignoringParenImpCasts(declRefExpr(hasPointerType(), - to(varDecl())). + toSupportedVariable()). bind(PointerAssignRHSTag))), hasLHS(declRefExpr(hasPointerType(), - to(varDecl())). + toSupportedVariable()). bind(PointerAssignLHSTag)))); return stmt(isInUnspecifiedUntypedContext(PtrAssignExpr)); @@ -691,7 +696,8 @@ class ULCArraySubscriptGadget : public FixableGadget { static Matcher matcher() { auto ArrayOrPtr = anyOf(hasPointerType(), hasArrayType()); auto BaseIsArrayOrPtrDRE = - hasBase(ignoringParenImpCasts(declRefExpr(ArrayOrPtr))); + hasBase(ignoringParenImpCasts(declRefExpr(ArrayOrPtr, + toSupportedVariable()))); auto Target = arraySubscriptExpr(BaseIsArrayOrPtrDRE).bind(ULCArraySubscriptTag); @@ -733,7 +739,8 @@ class UPCStandalonePointerGadget : public FixableGadget { static Matcher matcher() { auto ArrayOrPtr = anyOf(hasPointerType(), hasArrayType()); auto target = expr( - ignoringParenImpCasts(declRefExpr(allOf(ArrayOrPtr, to(varDecl()))).bind(DeclRefExprTag))); + ignoringParenImpCasts(declRefExpr(allOf(ArrayOrPtr, + toSupportedVariable())).bind(DeclRefExprTag))); return stmt(isInUnspecifiedPointerContext(target)); } @@ -769,7 +776,7 @@ class PointerDereferenceGadget : public FixableGadget { unaryOperator( hasOperatorName("*"), has(expr(ignoringParenImpCasts( - declRefExpr(to(varDecl())).bind(BaseDeclRefExprTag))))) + declRefExpr(toSupportedVariable()).bind(BaseDeclRefExprTag))))) .bind(OperatorTag); return expr(isInUnspecifiedLvalueContext(Target)); @@ -809,7 +816,8 @@ class UPCAddressofArraySubscriptGadget : public FixableGadget { return expr(isInUnspecifiedPointerContext(expr(ignoringImpCasts( unaryOperator(hasOperatorName("&"), hasUnaryOperand(arraySubscriptExpr( - hasBase(ignoringParenImpCasts(declRefExpr()))))) + hasBase(ignoringParenImpCasts(declRefExpr( + toSupportedVariable())))))) .bind(UPCAddressofArraySubscriptTag))))); } @@ -961,7 +969,8 @@ class UPCPreIncrementGadget : public FixableGadget { // things right. return stmt(isInUnspecifiedPointerContext(expr(ignoringImpCasts( unaryOperator(isPreInc(), - hasUnaryOperand(declRefExpr()) + hasUnaryOperand(declRefExpr( + toSupportedVariable())) ).bind(UPCPreIncrementTag))))); } @@ -999,7 +1008,8 @@ class DerefSimplePtrArithFixableGadget : public FixableGadget { static Matcher matcher() { // clang-format off auto ThePtr = expr(hasPointerType(), - ignoringImpCasts(declRefExpr(to(varDecl())).bind(BaseDeclRefExprTag))); + ignoringImpCasts(declRefExpr(toSupportedVariable()). + bind(BaseDeclRefExprTag))); auto PlusOverPtrAndInteger = expr(anyOf( binaryOperator(hasOperatorName("+"), hasLHS(ThePtr), hasRHS(integerLiteral().bind(OffsetTag))) @@ -1106,7 +1116,7 @@ findGadgets(const Decl *D, const UnsafeBufferUsageHandler &Handler, // In parallel, match all DeclRefExprs so that to find out // whether there are any uncovered by gadgets. declRefExpr(anyOf(hasPointerType(), hasArrayType()), - to(varDecl())).bind("any_dre"), + to(anyOf(varDecl(), bindingDecl()))).bind("any_dre"), // Also match DeclStmts because we'll need them when fixing // their underlying VarDecls that otherwise don't have // any backreferences to DeclStmts. diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-debug.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-debug.cpp index f0f9a52cc3d0c..e08f70d97e391 100644 --- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-debug.cpp +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-debug.cpp @@ -78,3 +78,23 @@ void test_decomp_decl() { auto [x, y] = a; x = 9; } + +void test_claim_use_multiple() { + int *a = new int[8]; // expected-warning{{'a' is an unsafe pointer used for buffer access}} + a[6] = 9; // expected-note{{used in buffer access here}} + a++; // expected-note{{used in pointer arithmetic here}} \ + // debug-note{{safe buffers debug: failed to produce fixit for 'a' : has an unclaimed use}} +} + +struct S +{ + int *x; +}; + +S f() { return S{new int[4]}; } + +void test_struct_claim_use() { + auto [x] = f(); + x[6] = 8; // expected-warning{{unsafe buffer access}} + x++; // expected-warning{{unsafe pointer arithmetic}} +}