[clang] 2afcda6 - [-Wunsafe-buffer-usage] Fix assertion failure in case of BindingDecl

Rashmi Mudduluru via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 17 16:18:51 PDT 2023


Author: Rashmi Mudduluru
Date: 2023-08-17T16:18:38-07:00
New Revision: 2afcda693acba8d63887a6bb0605038b1563c64c

URL: https://github.com/llvm/llvm-project/commit/2afcda693acba8d63887a6bb0605038b1563c64c
DIFF: https://github.com/llvm/llvm-project/commit/2afcda693acba8d63887a6bb0605038b1563c64c.diff

LOG: [-Wunsafe-buffer-usage] Fix assertion failure in case of BindingDecl

Differential Revision: https://reviews.llvm.org/D158112#inline-1530312

Added: 
    

Modified: 
    clang/lib/Analysis/UnsafeBufferUsage.cpp
    clang/test/SemaCXX/warn-unsafe-buffer-usage-debug.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 41820c80da6b4b..2c36d78e60c89b 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<std::unique_ptr<FixableGadget>>;
 using WarningGadgetList = std::vector<std::unique_ptr<WarningGadget>>;
 
@@ -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 f0f9a52cc3d0c9..e08f70d97e3912 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}}
+}


        


More information about the cfe-commits mailing list