Hi,

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. Comments?

Regards,
Daniel Fahlgren
Index: test/Analysis/bstring.c
===================================================================
--- test/Analysis/bstring.c	(revision 217630)
+++ test/Analysis/bstring.c	(working copy)
@@ -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}}
Index: lib/StaticAnalyzer/Checkers/CStringChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/CStringChecker.cpp	(revision 217630)
+++ lib/StaticAnalyzer/Checkers/CStringChecker.cpp	(working copy)
@@ -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());
       
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to