r219024 - [analyzer] Make CStringChecker correctly calculate return value of mempcpy

Anna Zaks ganna at apple.com
Fri Oct 3 14:48:54 PDT 2014


Author: zaks
Date: Fri Oct  3 16:48:54 2014
New Revision: 219024

URL: http://llvm.org/viewvc/llvm-project?rev=219024&view=rev
Log:
[analyzer] Make CStringChecker correctly calculate return value of mempcpy

The return value of mempcpy is only correct when the destination type is
one byte in size. This patch casts the argument to a char* so the
calculation is also correct for structs, ints etc.

A patch by Daniel Fahlgren!

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=219024&r1=219023&r2=219024&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Fri Oct  3 16:48:54 2014
@@ -969,8 +969,13 @@ void CStringChecker::evalCopyCommon(Chec
       // Get the length to copy.
       if (Optional<NonLoc> lenValNonLoc = sizeVal.getAs<NonLoc>()) {
         // Get the byte after the last byte copied.
+        SValBuilder &SvalBuilder = C.getSValBuilder();
+        ASTContext &Ctx = SvalBuilder.getContext();
+        QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
+        loc::MemRegionVal DestRegCharVal = SvalBuilder.evalCast(destRegVal,
+          CharPtrTy, Dest->getType()).castAs<loc::MemRegionVal>();
         SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add, 
-                                                          destRegVal,
+                                                          DestRegCharVal,
                                                           *lenValNonLoc, 
                                                           Dest->getType());
       

Modified: cfe/trunk/test/Analysis/bstring.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/bstring.c?rev=219024&r1=219023&r2=219024&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/bstring.c (original)
+++ cfe/trunk/test/Analysis/bstring.c Fri Oct  3 16:48:54 2014
@@ -257,6 +257,45 @@ void mempcpy13() {
   mempcpy(a, 0, 0); // no-warning
 }
 
+void mempcpy14() {
+  int src[] = {1, 2, 3, 4};
+  int dst[5] = {0};
+  int *p;
+
+  p = mempcpy(dst, src, 4 * sizeof(int));
+
+  clang_analyzer_eval(p == &dst[4]); // expected-warning{{TRUE}}
+}
+
+struct st {
+  int i;
+  int j;
+};
+
+void mempcpy15() {
+  struct st s1 = {0};
+  struct st s2;
+  struct st *p1;
+  struct st *p2;
+
+  p1 = (&s2) + 1;
+  p2 = mempcpy(&s2, &s1, sizeof(struct st));
+
+  clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}
+}
+
+void mempcpy16() {
+  struct st s1[10] = {{0}};
+  struct st s2[10];
+  struct st *p1;
+  struct st *p2;
+
+  p1 = (&s2[0]) + 5;
+  p2 = mempcpy(&s2[0], &s1[0], 5 * sizeof(struct st));
+
+  clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}
+}
+
 void mempcpy_unknown_size_warn (size_t n) {
   char a[4];
   void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}





More information about the cfe-commits mailing list