]> granicus.if.org Git - clang/commitdiff
Directly compare the StackFrameContext. This greatly simplifies logic and
authorZhongxing Xu <xuzhongxing@gmail.com>
Wed, 9 Jun 2010 05:50:38 +0000 (05:50 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Wed, 9 Jun 2010 05:50:38 +0000 (05:50 +0000)
improves generality. Thanks Ted.

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

lib/Checker/StackAddrLeakChecker.cpp
test/Analysis/stackaddrleak.c

index 0bd9e02448661781b63274fe6af33e9e54ede1c0..8aa359e49ef16bee34b67514d0759992a0672296 100644 (file)
@@ -54,41 +54,34 @@ void StackAddrLeakChecker::EvalEndPath(GREndPathNodeBuilder &B, void *tag,
       SVal V = state->getSVal(cast<Loc>(L));
       if (loc::MemRegionVal *RV = dyn_cast<loc::MemRegionVal>(&V)) {
         const MemRegion *R = RV->getRegion();
-        // Strip fields or elements to get the variable region.
-        R = R->getBaseRegion();
-        if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
-          const VarDecl *VD = VR->getDecl();
-          const DeclContext *DC = VD->getDeclContext();
-          // Get the function where the variable is declared.
-          if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DC)) {
-            // Check if the function is the function we are leaving.
-            if (FD == LCtx->getDecl()) {
-              // The variable is declared in the function scope which we are 
-              // leaving. Keeping this variable's address in a global variable
-              // is dangerous.
-              // FIXME: Currently VarRegion does not carry context information.
-              // So we cannot tell if the local variable instance is in the
-              // current stack frame. This may produce false positive in 
-              // recursive function call context. But that's a rare case.
 
-              // FIXME: better warning location.
+        if (const StackSpaceRegion *SSR = 
+                              dyn_cast<StackSpaceRegion>(R->getMemorySpace())) {
+          const StackFrameContext *ValSFC = SSR->getStackFrame();
+          const StackFrameContext *CurSFC = LCtx->getCurrentStackFrame();
+          // If the global variable holds a location in the current stack frame,
+          // emit a warning.
+          if (ValSFC == CurSFC) {
+            // The variable is declared in the function scope which we are 
+            // leaving. Keeping this variable's address in a global variable
+            // is dangerous.
 
-              ExplodedNode *N = B.generateNode(state, tag, B.getPredecessor());
-              if (N) {
-                if (!BT_stackleak)
-                  BT_stackleak = new BuiltinBug("Stack address leak",
-                    "Stack address was saved into a global variable. "
-                    "This is dangerous because the address will become invalid "
-                    "after returning from the function.");
-                BugReport *R = new BugReport(*BT_stackleak, 
-                                             BT_stackleak->getDescription(), N);
-                Eng.getBugReporter().EmitReport(R);
-              }
+            // FIXME: better warning location.
+            
+            ExplodedNode *N = B.generateNode(state, tag, B.getPredecessor());
+            if (N) {
+              if (!BT_stackleak)
+                BT_stackleak = new BuiltinBug("Stack address leak",
+                        "Stack address was saved into a global variable. "
+                        "is dangerous because the address will become invalid "
+                        "after returning from the function.");
+              BugReport *R = new BugReport(*BT_stackleak, 
+                                           BT_stackleak->getDescription(), N);
+              Eng.getBugReporter().EmitReport(R);
             }
-          }            
+          }
         }
       }
     }
   }
 }
-
index 0076b27a3cfd280396615896cab7aed4feaa30f8..b9088fa81b9b1ab473e1bac7dd1a90542336903d 100644 (file)
@@ -12,3 +12,7 @@ void f1() {
   p = str; 
   p = 0; // no-warning
 }
+
+void f2() {
+  p = (const char *) __builtin_alloca(12); // expected-warning {{Stack address was saved into a global variable.}}
+}