r288260 - [analyzer] SValExplainer: Support ObjC ivars and __block variables.

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 30 10:26:44 PST 2016


Author: dergachev
Date: Wed Nov 30 12:26:43 2016
New Revision: 288260

URL: http://llvm.org/viewvc/llvm-project?rev=288260&view=rev
Log:
[analyzer] SValExplainer: Support ObjC ivars and __block variables.

Additionally, explain the difference between normal and heap-based
symbolic regions.

Added:
    cfe/trunk/test/Analysis/explain-svals.m
Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
    cfe/trunk/test/Analysis/explain-svals.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h?rev=288260&r1=288259&r2=288260&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h Wed Nov 30 12:26:43 2016
@@ -142,6 +142,14 @@ public:
     // TODO: Explain CXXThisRegion itself, find a way to test it.
     if (isThisObject(R))
       return "'this' object";
+    // Objective-C objects are not normal symbolic regions. At least,
+    // they're always on the heap.
+    if (R->getSymbol()->getType()
+            .getCanonicalType()->getAs<ObjCObjectPointerType>())
+      return "object at " + Visit(R->getSymbol());
+    // Other heap-based symbolic regions are also special.
+    if (isa<HeapSpaceRegion>(R->getMemorySpace()))
+      return "heap segment that starts at " + Visit(R->getSymbol());
     return "pointee of " + Visit(R->getSymbol());
   }
 
@@ -176,6 +184,8 @@ public:
     std::string Name = VD->getQualifiedNameAsString();
     if (isa<ParmVarDecl>(VD))
       return "parameter '" + Name + "'";
+    else if (VD->hasAttr<BlocksAttr>())
+      return "block variable '" + Name + "'";
     else if (VD->hasLocalStorage())
       return "local variable '" + Name + "'";
     else if (VD->isStaticLocal())
@@ -186,6 +196,11 @@ public:
       llvm_unreachable("A variable is either local or global");
   }
 
+  std::string VisitObjCIvarRegion(const ObjCIvarRegion *R) {
+    return "instance variable '" + R->getDecl()->getNameAsString() + "' of " +
+           Visit(R->getSuperRegion());
+  }
+
   std::string VisitFieldRegion(const FieldRegion *R) {
     return "field '" + R->getDecl()->getNameAsString() + "' of " +
            Visit(R->getSuperRegion());

Modified: cfe/trunk/test/Analysis/explain-svals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/explain-svals.cpp?rev=288260&r1=288259&r2=288260&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/explain-svals.cpp (original)
+++ cfe/trunk/test/Analysis/explain-svals.cpp Wed Nov 30 12:26:43 2016
@@ -47,7 +47,7 @@ void test_2(char *ptr, int ext) {
   clang_analyzer_explain(glob_ptr); // expected-warning-re{{{{^value derived from \(symbol of type 'int' conjured at statement 'conjure\(\)'\) for global variable 'glob_ptr'$}}}}
   clang_analyzer_explain(clang_analyzer_getExtent(ptr)); // expected-warning-re{{{{^extent of pointee of argument 'ptr'$}}}}
   int *x = new int[ext];
-  clang_analyzer_explain(x); // expected-warning-re{{{{^pointer to element of type 'int' with index 0 of pointee of symbol of type 'int \*' conjured at statement 'new int \[ext\]'$}}}}
+  clang_analyzer_explain(x); // expected-warning-re{{{{^pointer to element of type 'int' with index 0 of heap segment that starts at symbol of type 'int \*' conjured at statement 'new int \[ext\]'$}}}}
   // Sic! What gets computed is the extent of the element-region.
   clang_analyzer_explain(clang_analyzer_getExtent(x)); // expected-warning-re{{{{^signed 32-bit integer '4'$}}}}
   delete[] x;

Added: cfe/trunk/test/Analysis/explain-svals.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/explain-svals.m?rev=288260&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/explain-svals.m (added)
+++ cfe/trunk/test/Analysis/explain-svals.m Wed Nov 30 12:26:43 2016
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -w -triple i386-apple-darwin10 -fblocks -analyze -analyzer-checker=core.builtin,debug.ExprInspection -verify %s
+
+#include "Inputs/system-header-simulator-objc.h"
+
+void clang_analyzer_explain(void *);
+
+ at interface Object : NSObject {
+ at public
+  Object *x;
+}
+ at end
+
+void test_1(Object *p) {
+  clang_analyzer_explain(p); // expected-warning-re{{{{^argument 'p'$}}}}
+  clang_analyzer_explain(p->x); // expected-warning-re{{{{^initial value of instance variable 'x' of object at argument 'p'$}}}}
+  Object *q = [[Object alloc] init];
+  clang_analyzer_explain(q); // expected-warning-re{{{{^symbol of type 'Object \*' conjured at statement '\[\[Object alloc\] init\]'$}}}}
+  clang_analyzer_explain(q->x); // expected-warning-re{{{{^initial value of instance variable 'x' of object at symbol of type 'Object \*' conjured at statement '\[\[Object alloc\] init\]'$}}}}
+}
+
+void test_2() {
+  __block int x;
+  ^{
+    clang_analyzer_explain(&x); // expected-warning-re{{{{^pointer to block variable 'x'$}}}}
+  };
+  clang_analyzer_explain(&x); // expected-warning-re{{{{^pointer to block variable 'x'$}}}}
+}




More information about the cfe-commits mailing list