]> granicus.if.org Git - clang/commitdiff
Always assume block-level expressions in the caller are alive when analyzing
authorZhongxing Xu <xuzhongxing@gmail.com>
Mon, 5 Apr 2010 13:16:29 +0000 (13:16 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Mon, 5 Apr 2010 13:16:29 +0000 (13:16 +0000)
the callee.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100429 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Checker/Environment.cpp
test/Analysis/inline4.c [new file with mode: 0644]

index e2568b66377b81b34acf97e49d0c6abb3bde0a90..be1a677d9118fb20561f3683676b82a38a2ee7e7 100644 (file)
@@ -96,6 +96,19 @@ public:
 };
 } // end anonymous namespace
 
+static bool isBlockExprInCallers(const Stmt *E, const LocationContext *LC) {
+  const LocationContext *ParentLC = LC->getParent();
+  while (ParentLC) {
+    CFG &C = *ParentLC->getCFG();
+    if (C.isBlkExpr(E))
+      return true;
+    ParentLC = ParentLC->getParent();
+  }
+
+  return false;
+}
+
+
 // RemoveDeadBindings:
 //  - Remove subexpression bindings.
 //  - Remove dead block expression bindings.
@@ -122,13 +135,27 @@ EnvironmentManager::RemoveDeadBindings(Environment Env, const Stmt *S,
        I != E; ++I) {
 
     const Stmt *BlkExpr = I.getKey();
+    const SVal &X = I.getData();
+
+    // Block-level expressions in callers are assumed always live.
+    if (isBlockExprInCallers(BlkExpr, SymReaper.getLocationContext())) {
+      NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
+
+      if (isa<loc::MemRegionVal>(X)) {
+        const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
+        DRoots.push_back(R);
+      }
+
+      // Mark all symbols in the block expr's value live.
+      MarkLiveCallback cb(SymReaper);
+      ST->scanReachableSymbols(X, cb);
+      continue;
+    }
 
     // Not a block-level expression?
     if (!C.isBlkExpr(BlkExpr))
       continue;
 
-    const SVal &X = I.getData();
-
     if (SymReaper.isLive(S, BlkExpr)) {
       // Copy the binding to the new map.
       NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
diff --git a/test/Analysis/inline4.c b/test/Analysis/inline4.c
new file mode 100644 (file)
index 0000000..dd2379f
--- /dev/null
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f -verify %s
+
+int g(int a) {    
+  return a;
+}
+
+int f(int a) {
+  // Do not remove block-level expression bindings of caller when analyzing 
+  // in the callee.
+  if (1 && g(a)) // The binding of '1 && g(a)' which is an UndefinedVal 
+                 // carries important information.
+    return 1;
+  return 0;
+}