r256885 - [analyzer] Don't report null dereferences on address_space annotated memory

Anna Zaks via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 5 16:32:49 PST 2016


Author: zaks
Date: Tue Jan  5 18:32:49 2016
New Revision: 256885

URL: http://llvm.org/viewvc/llvm-project?rev=256885&view=rev
Log:
[analyzer] Don't report null dereferences on address_space annotated memory

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
    cfe/trunk/test/Analysis/null-deref-ps.c
    cfe/trunk/test/Analysis/nullptr.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp?rev=256885&r1=256884&r2=256885&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp Tue Jan  5 18:32:49 2016
@@ -34,8 +34,7 @@ class DereferenceChecker
   mutable std::unique_ptr<BuiltinBug> BT_null;
   mutable std::unique_ptr<BuiltinBug> BT_undef;
 
-  void reportBug(ProgramStateRef State, const Stmt *S, CheckerContext &C,
-                 bool IsBind = false) const;
+  void reportBug(ProgramStateRef State, const Stmt *S, CheckerContext &C) const;
 
 public:
   void checkLocation(SVal location, bool isLoad, const Stmt* S,
@@ -89,8 +88,31 @@ DereferenceChecker::AddDerefSource(raw_o
   }
 }
 
+static const Expr *getDereferenceExpr(const Stmt *S, bool IsBind=false){
+  const Expr *E = nullptr;
+
+  // Walk through lvalue casts to get the original expression
+  // that syntactically caused the load.
+  if (const Expr *expr = dyn_cast<Expr>(S))
+    E = expr->IgnoreParenLValueCasts();
+
+  if (IsBind) {
+    const VarDecl *VD;
+    const Expr *Init;
+    std::tie(VD, Init) = parseAssignment(S);
+    if (VD && Init)
+      E = Init;
+  }
+  return E;
+}
+
+static bool suppressReport(const Expr *E) {
+  // Do not report dereferences on memory in non-default address spaces.
+  return E->getType().getQualifiers().hasAddressSpace();
+}
+
 void DereferenceChecker::reportBug(ProgramStateRef State, const Stmt *S,
-                                   CheckerContext &C, bool IsBind) const {
+                                   CheckerContext &C) const {
   // Generate an error node.
   ExplodedNode *N = C.generateErrorNode(State);
   if (!N)
@@ -106,19 +128,6 @@ void DereferenceChecker::reportBug(Progr
 
   SmallVector<SourceRange, 2> Ranges;
 
-  // Walk through lvalue casts to get the original expression
-  // that syntactically caused the load.
-  if (const Expr *expr = dyn_cast<Expr>(S))
-    S = expr->IgnoreParenLValueCasts();
-
-  if (IsBind) {
-    const VarDecl *VD;
-    const Expr *Init;
-    std::tie(VD, Init) = parseAssignment(S);
-    if (VD && Init)
-      S = Init;
-  }
-
   switch (S->getStmtClass()) {
   case Stmt::ArraySubscriptExprClass: {
     os << "Array access";
@@ -209,8 +218,11 @@ void DereferenceChecker::checkLocation(S
   // The explicit NULL case.
   if (nullState) {
     if (!notNullState) {
-      reportBug(nullState, S, C);
-      return;
+      const Expr *expr = getDereferenceExpr(S);
+      if (!suppressReport(expr)) {
+        reportBug(nullState, expr, C);
+        return;
+      }
     }
 
     // Otherwise, we have the case where the location could either be
@@ -248,8 +260,11 @@ void DereferenceChecker::checkBind(SVal
 
   if (StNull) {
     if (!StNonNull) {
-      reportBug(StNull, S, C, /*isBind=*/true);
-      return;
+      const Expr *expr = getDereferenceExpr(S, /*IsBind=*/true);
+      if (!suppressReport(expr)) {
+        reportBug(StNull, expr, C);
+        return;
+      }
     }
 
     // At this point the value could be either null or non-null.

Modified: cfe/trunk/test/Analysis/null-deref-ps.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/null-deref-ps.c?rev=256885&r1=256884&r2=256885&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/null-deref-ps.c (original)
+++ cfe/trunk/test/Analysis/null-deref-ps.c Tue Jan  5 18:32:49 2016
@@ -311,3 +311,21 @@ int foo10595327(int b) {
       return *p; // no-warning
   return 0;
 }
+
+#define AS_ATTRIBUTE volatile __attribute__((address_space(256)))
+#define _get_base() ((void * AS_ATTRIBUTE *)0)
+void* test_address_space_array(unsigned long slot) {
+  return _get_base()[slot]; // no-warning
+}
+void test_address_space_condition(int AS_ATTRIBUTE *cpu_data) {
+   if (cpu_data == 0) {
+    *cpu_data = 3; // no-warning
+  }
+}
+struct X { int member; };
+int test_address_space_member() {
+  struct X AS_ATTRIBUTE *data = (struct X AS_ATTRIBUTE *)0UL;
+  int ret;
+  ret = data->member; // no-warning
+  return ret;
+}

Modified: cfe/trunk/test/Analysis/nullptr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/nullptr.cpp?rev=256885&r1=256884&r2=256885&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/nullptr.cpp (original)
+++ cfe/trunk/test/Analysis/nullptr.cpp Tue Jan  5 18:32:49 2016
@@ -126,3 +126,22 @@ decltype(nullptr) returnsNullPtrType();
 void fromReturnType() {
   ((X *)returnsNullPtrType())->f(); // expected-warning{{Called C++ object pointer is null}}
 }
+
+#define AS_ATTRIBUTE __attribute__((address_space(256)))
+class AS1 {
+public:
+  int x;
+  ~AS1() {
+    int AS_ATTRIBUTE *x = 0;
+    *x = 3; // no-warning
+  }
+};
+void test_address_space_field_access() {
+  AS1 AS_ATTRIBUTE *pa = 0;
+  pa->x = 0; // no-warning
+}
+void test_address_space_bind() {
+  AS1 AS_ATTRIBUTE *pa = 0;
+  AS1 AS_ATTRIBUTE &r = *pa;
+  r.x = 0; // no-warning
+}




More information about the cfe-commits mailing list