balazske created this revision.
Herald added subscribers: cfe-commits, ASDenysPetrov, martong, Charusso, 
gamesh411, dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, 
baloghadamsoftware, xazax.hun.
Herald added a reviewer: Szelethus.
Herald added a project: clang.

Report undefined pointer dereference in similar way as null pointer dereference.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84520

Files:
  clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
  clang/test/Analysis/Inputs/expected-plists/null-deref-path-notes.m.plist
  clang/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist
  clang/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist
  clang/test/Analysis/misc-ps-region-store.m
  clang/test/Analysis/null-deref-offsets.c
  clang/test/Analysis/null-deref-path-notes.c
  clang/test/Analysis/null-deref-path-notes.cpp
  clang/test/Analysis/null-deref-path-notes.m
  clang/test/Analysis/null-deref-ps.c
  clang/test/Analysis/silence-checkers-and-packages-core-div-by-zero.cpp

Index: clang/test/Analysis/silence-checkers-and-packages-core-div-by-zero.cpp
===================================================================
--- clang/test/Analysis/silence-checkers-and-packages-core-div-by-zero.cpp
+++ clang/test/Analysis/silence-checkers-and-packages-core-div-by-zero.cpp
@@ -14,5 +14,5 @@
     return;
 
   int x = p[0];
-  // expected-warning@-1 {{Array access (from variable 'p') results in a null pointer dereference}}
+  // expected-warning@-1 {{Array access (from variable 'p') results in a dereference of a null pointer}}
 }
Index: clang/test/Analysis/null-deref-ps.c
===================================================================
--- clang/test/Analysis/null-deref-ps.c
+++ clang/test/Analysis/null-deref-ps.c
@@ -34,7 +34,7 @@
   if (x)
     return x[i - 1];
   
-  return x[i+1]; // expected-warning{{Array access (from variable 'x') results in a null pointer dereference}}
+  return x[i+1]; // expected-warning{{Array access (from variable 'x') results in a dereference of a null pointer}}
 }
 
 int f3_b(char* x) {
@@ -44,7 +44,7 @@
   if (x)
     return x[i - 1];
   
-  return x[i+1]++; // expected-warning{{Array access (from variable 'x') results in a null pointer dereference}}
+  return x[i+1]++; // expected-warning{{Array access (from variable 'x') results in a dereference of a null pointer}}
 }
 
 int f4(int *p) {
Index: clang/test/Analysis/null-deref-path-notes.m
===================================================================
--- clang/test/Analysis/null-deref-path-notes.m
+++ clang/test/Analysis/null-deref-path-notes.m
@@ -58,8 +58,8 @@
 @public int *p;
 }
 - (void)useArray {
-  p[1] = 2; // expected-warning{{Array access (via ivar 'p') results in a null pointer dereference}}
-            // expected-note@-1{{Array access (via ivar 'p') results in a null pointer dereference}}
+  p[1] = 2; // expected-warning{{Array access (via ivar 'p') results in a dereference of a null pointer}}
+            // expected-note@-1{{Array access (via ivar 'p') results in a dereference of a null pointer}}
 }
 @end
 
Index: clang/test/Analysis/null-deref-path-notes.cpp
===================================================================
--- clang/test/Analysis/null-deref-path-notes.cpp
+++ clang/test/Analysis/null-deref-path-notes.cpp
@@ -15,8 +15,8 @@
 // Properly track the null pointer in the array field back to the default
 // constructor of 'h'.
 void c::f(B &g, int &i) {
-  e(g.d[9], i); // expected-warning{{Array access (via field 'd') results in a null pointer dereference}}
-                // expected-note@-1{{Array access (via field 'd') results in a null pointer dereference}}
+  e(g.d[9], i); // expected-warning{{Array access (via field 'd') results in a dereference of a null pointer}}
+                // expected-note@-1{{Array access (via field 'd') results in a dereference of a null pointer}}
   B h, a; // expected-note{{Value assigned to 'h.d'}}
   a.d == __null; // expected-note{{Assuming the condition is true}}
   a.d != h.d; // expected-note{{Assuming 'a.d' is equal to 'h.d'}}
Index: clang/test/Analysis/null-deref-path-notes.c
===================================================================
--- clang/test/Analysis/null-deref-path-notes.c
+++ clang/test/Analysis/null-deref-path-notes.c
@@ -4,8 +4,8 @@
 // of the null pointer for path notes.
 void pr34373() {
   int *a = 0; // expected-note{{'a' initialized to a null pointer value}}
-  (a + 0)[0]; // expected-warning{{Array access results in a null pointer dereference}}
-              // expected-note@-1{{Array access results in a null pointer dereference}}
+  (a + 0)[0]; // expected-warning{{Array access results in a dereference of a null pointer}}
+              // expected-note@-1{{Array access results in a dereference of a null pointer}}
 }
 
 typedef __typeof(sizeof(int)) size_t;
Index: clang/test/Analysis/null-deref-offsets.c
===================================================================
--- clang/test/Analysis/null-deref-offsets.c
+++ clang/test/Analysis/null-deref-offsets.c
@@ -33,5 +33,5 @@
   if (coin)
     s->y = 5; // expected-warning{{Access to field 'y' results in a dereference of a null pointer (loaded from variable 's')}}
   else
-    s->z[1] = 6; // expected-warning{{Array access (via field 'z') results in a null pointer dereference}}
+    s->z[1] = 6; // expected-warning{{Array access (via field 'z') results in a dereference of a null pointer}}
 }
Index: clang/test/Analysis/misc-ps-region-store.m
===================================================================
--- clang/test/Analysis/misc-ps-region-store.m
+++ clang/test/Analysis/misc-ps-region-store.m
@@ -1157,7 +1157,7 @@
 struct list_pr8141 *
 pr8141 (void) {
   struct list_pr8141 *items;
-  for (;; items = ({ do { } while (0); items->tail; })) // expected-warning{{Dereference of undefined pointer value}}
+  for (;; items = ({ do { } while (0); items->tail; })) // expected-warning{{dereference of an undefined pointer value}}
     {
     }
 }
Index: clang/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist
===================================================================
--- clang/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist
+++ clang/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist
@@ -9738,12 +9738,12 @@
      </array>
      <key>depth</key><integer>0</integer>
      <key>extended_message</key>
-     <string>Array access (from variable &apos;kindC&apos;) results in a null pointer dereference</string>
+     <string>Array access (from variable &apos;kindC&apos;) results in a dereference of a null pointer</string>
      <key>message</key>
-     <string>Array access (from variable &apos;kindC&apos;) results in a null pointer dereference</string>
+     <string>Array access (from variable &apos;kindC&apos;) results in a dereference of a null pointer</string>
     </dict>
    </array>
-   <key>description</key><string>Array access (from variable &apos;kindC&apos;) results in a null pointer dereference</string>
+   <key>description</key><string>Array access (from variable &apos;kindC&apos;) results in a dereference of a null pointer</string>
    <key>category</key><string>Memory error</string>
    <key>type</key><string>Dereference of null pointer</string>
    <key>check_name</key><string>core.NullDereference</string>
Index: clang/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist
===================================================================
--- clang/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist
+++ clang/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist
@@ -9738,12 +9738,12 @@
      </array>
      <key>depth</key><integer>0</integer>
      <key>extended_message</key>
-     <string>Array access (from variable &apos;kindC&apos;) results in a null pointer dereference</string>
+     <string>Array access (from variable &apos;kindC&apos;) results in a dereference of a null pointer</string>
      <key>message</key>
-     <string>Array access (from variable &apos;kindC&apos;) results in a null pointer dereference</string>
+     <string>Array access (from variable &apos;kindC&apos;) results in a dereference of a null pointer</string>
     </dict>
    </array>
-   <key>description</key><string>Array access (from variable &apos;kindC&apos;) results in a null pointer dereference</string>
+   <key>description</key><string>Array access (from variable &apos;kindC&apos;) results in a dereference of a null pointer</string>
    <key>category</key><string>Memory error</string>
    <key>type</key><string>Dereference of null pointer</string>
    <key>check_name</key><string>core.NullDereference</string>
Index: clang/test/Analysis/Inputs/expected-plists/null-deref-path-notes.m.plist
===================================================================
--- clang/test/Analysis/Inputs/expected-plists/null-deref-path-notes.m.plist
+++ clang/test/Analysis/Inputs/expected-plists/null-deref-path-notes.m.plist
@@ -986,12 +986,12 @@
      </array>
      <key>depth</key><integer>1</integer>
      <key>extended_message</key>
-     <string>Array access (via ivar &apos;p&apos;) results in a null pointer dereference</string>
+     <string>Array access (via ivar &apos;p&apos;) results in a dereference of a null pointer</string>
      <key>message</key>
-     <string>Array access (via ivar &apos;p&apos;) results in a null pointer dereference</string>
+     <string>Array access (via ivar &apos;p&apos;) results in a dereference of a null pointer</string>
     </dict>
    </array>
-   <key>description</key><string>Array access (via ivar &apos;p&apos;) results in a null pointer dereference</string>
+   <key>description</key><string>Array access (via ivar &apos;p&apos;) results in a dereference of a null pointer</string>
    <key>category</key><string>Memory error</string>
    <key>type</key><string>Dereference of null pointer</string>
    <key>check_name</key><string>core.NullDereference</string>
Index: clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
@@ -30,11 +30,14 @@
     : public Checker< check::Location,
                       check::Bind,
                       EventDispatcher<ImplicitNullDerefEvent> > {
+  enum DerefKind { NullPointer, UndefinedPointerValue };
+
   BugType BT_Null{this, "Dereference of null pointer", categories::MemoryError};
   BugType BT_Undef{this, "Dereference of undefined pointer value",
                    categories::MemoryError};
 
-  void reportBug(ProgramStateRef State, const Stmt *S, CheckerContext &C) const;
+  void reportBug(DerefKind K, ProgramStateRef State, const Stmt *S,
+                 CheckerContext &C) const;
 
 public:
   void checkLocation(SVal location, bool isLoad, const Stmt* S,
@@ -117,8 +120,21 @@
   return false;
 }
 
-void DereferenceChecker::reportBug(ProgramStateRef State, const Stmt *S,
-                                   CheckerContext &C) const {
+void DereferenceChecker::reportBug(DerefKind K, ProgramStateRef State,
+                                   const Stmt *S, CheckerContext &C) const {
+  const BugType *BT = nullptr;
+  llvm::StringRef DerefKindStr;
+  switch (K) {
+  case DerefKind::NullPointer:
+    BT = &BT_Null;
+    DerefKindStr = "dereference of a null pointer";
+    break;
+  case DerefKind::UndefinedPointerValue:
+    BT = &BT_Undef;
+    DerefKindStr = "dereference of an undefined pointer value";
+    break;
+  };
+
   // Generate an error node.
   ExplodedNode *N = C.generateErrorNode(State);
   if (!N)
@@ -135,7 +151,7 @@
     const ArraySubscriptExpr *AE = cast<ArraySubscriptExpr>(S);
     AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(),
                    State.get(), N->getLocationContext());
-    os << " results in a null pointer dereference";
+    os << " results in a " << DerefKindStr;
     break;
   }
   case Stmt::OMPArraySectionExprClass: {
@@ -143,11 +159,11 @@
     const OMPArraySectionExpr *AE = cast<OMPArraySectionExpr>(S);
     AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(),
                    State.get(), N->getLocationContext());
-    os << " results in a null pointer dereference";
+    os << " results in a " << DerefKindStr;
     break;
   }
   case Stmt::UnaryOperatorClass: {
-    os << "Dereference of null pointer";
+    os << BT->getDescription();
     const UnaryOperator *U = cast<UnaryOperator>(S);
     AddDerefSource(os, Ranges, U->getSubExpr()->IgnoreParens(),
                    State.get(), N->getLocationContext(), true);
@@ -156,8 +172,8 @@
   case Stmt::MemberExprClass: {
     const MemberExpr *M = cast<MemberExpr>(S);
     if (M->isArrow() || isDeclRefExprToReference(M->getBase())) {
-      os << "Access to field '" << M->getMemberNameInfo()
-         << "' results in a dereference of a null pointer";
+      os << "Access to field '" << M->getMemberNameInfo() << "' results in a "
+         << DerefKindStr;
       AddDerefSource(os, Ranges, M->getBase()->IgnoreParenCasts(),
                      State.get(), N->getLocationContext(), true);
     }
@@ -165,8 +181,8 @@
   }
   case Stmt::ObjCIvarRefExprClass: {
     const ObjCIvarRefExpr *IV = cast<ObjCIvarRefExpr>(S);
-    os << "Access to instance variable '" << *IV->getDecl()
-       << "' results in a dereference of a null pointer";
+    os << "Access to instance variable '" << *IV->getDecl() << "' results in a "
+       << DerefKindStr;
     AddDerefSource(os, Ranges, IV->getBase()->IgnoreParenCasts(),
                    State.get(), N->getLocationContext(), true);
     break;
@@ -176,7 +192,7 @@
   }
 
   auto report = std::make_unique<PathSensitiveBugReport>(
-      BT_Null, buf.empty() ? BT_Null.getDescription() : StringRef(buf), N);
+      *BT, buf.empty() ? BT->getDescription() : StringRef(buf), N);
 
   bugreporter::trackExpressionValue(N, bugreporter::getDerefExpr(S), *report);
 
@@ -191,12 +207,9 @@
                                        CheckerContext &C) const {
   // Check for dereference of an undefined value.
   if (l.isUndef()) {
-    if (ExplodedNode *N = C.generateErrorNode()) {
-      auto report = std::make_unique<PathSensitiveBugReport>(
-          BT_Undef, BT_Undef.getDescription(), N);
-      bugreporter::trackExpressionValue(N, bugreporter::getDerefExpr(S), *report);
-      C.emitReport(std::move(report));
-    }
+    const Expr *DerefExpr = getDereferenceExpr(S);
+    if (!suppressReport(DerefExpr))
+      reportBug(DerefKind::UndefinedPointerValue, C.getState(), DerefExpr, C);
     return;
   }
 
@@ -218,7 +231,7 @@
     if (!notNullState) {
       const Expr *expr = getDereferenceExpr(S);
       if (!suppressReport(expr)) {
-        reportBug(nullState, expr, C);
+        reportBug(DerefKind::NullPointer, nullState, expr, C);
         return;
       }
     }
@@ -260,7 +273,7 @@
     if (!StNonNull) {
       const Expr *expr = getDereferenceExpr(S, /*IsBind=*/true);
       if (!suppressReport(expr)) {
-        reportBug(StNull, expr, C);
+        reportBug(DerefKind::NullPointer, StNull, expr, C);
         return;
       }
     }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to