[cfe-commits] r132617 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/CStringChecker.cpp test/Analysis/bstring.c

Jordy Rose jediknil at belkadan.com
Fri Jun 3 18:47:27 PDT 2011


Author: jrose
Date: Fri Jun  3 20:47:27 2011
New Revision: 132617

URL: http://llvm.org/viewvc/llvm-project?rev=132617&view=rev
Log:
[analyzer] Don't crash when copying an unknown number of bytes with memcpy(). Also handle all memcpy-family return values in evalCopyCommon(), rather than having some outside and some inside.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
    cfe/trunk/test/Analysis/bstring.c

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp?rev=132617&r1=132616&r2=132617&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Fri Jun  3 20:47:27 2011
@@ -748,19 +748,33 @@
       // bind the expr.
       if (IsMempcpy) {
         loc::MemRegionVal *destRegVal = dyn_cast<loc::MemRegionVal>(&destVal);
+        assert(destRegVal && "Destination should be a known MemRegionVal here");
         
         // Get the length to copy.
-        SVal lenVal = state->getSVal(Size);
-        NonLoc *lenValNonLoc = dyn_cast<NonLoc>(&lenVal);
+        NonLoc *lenValNonLoc = dyn_cast<NonLoc>(&sizeVal);
         
-        // Get the byte after the last byte copied.
-        SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add, 
-                                                          *destRegVal,
-                                                          *lenValNonLoc, 
-                                                          Dest->getType());
+        if (lenValNonLoc) {
+          // Get the byte after the last byte copied.
+          SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add, 
+                                                            *destRegVal,
+                                                            *lenValNonLoc, 
+                                                            Dest->getType());
         
-        // The byte after the last byte copied is the return value.
-        state = state->BindExpr(CE, lastElement);
+          // The byte after the last byte copied is the return value.
+          state = state->BindExpr(CE, lastElement);
+        } else {
+          // If we don't know how much we copied, we can at least
+          // conjure a return value for later.
+          unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
+          SVal result =
+            C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
+          state = state->BindExpr(CE, result);
+        }
+
+      } else {
+        // All other copies return the destination buffer.
+        // (Well, bcopy() has a void return type, but this won't hurt.)
+        state = state->BindExpr(CE, destVal);
       }
 
       // Invalidate the destination.
@@ -780,7 +794,7 @@
   // The return value is the address of the destination buffer.
   const Expr *Dest = CE->getArg(0);
   const GRState *state = C.getState();
-  state = state->BindExpr(CE, state->getSVal(Dest));
+
   evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true);
 }
 
@@ -798,7 +812,7 @@
   // The return value is the address of the destination buffer.
   const Expr *Dest = CE->getArg(0);
   const GRState *state = C.getState();
-  state = state->BindExpr(CE, state->getSVal(Dest));
+
   evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1));
 }
 

Modified: cfe/trunk/test/Analysis/bstring.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/bstring.c?rev=132617&r1=132616&r2=132617&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/bstring.c (original)
+++ cfe/trunk/test/Analysis/bstring.c Fri Jun  3 20:47:27 2011
@@ -264,6 +264,12 @@
     (void)*(char*)0; // no-warning
 }
 
+void mempcpy_unknownable_size (char *src, float n) {
+  char a[4];
+  // This used to crash because we don't model floats.
+  mempcpy(a, src, (size_t)n);
+}
+
 //===----------------------------------------------------------------------===
 // memmove()
 //===----------------------------------------------------------------------===





More information about the cfe-commits mailing list