]> granicus.if.org Git - clang/commitdiff
Skip both character pointers and void pointers when diagnosing bad
authorChandler Carruth <chandlerc@gmail.com>
Thu, 16 Jun 2011 02:00:04 +0000 (02:00 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Thu, 16 Jun 2011 02:00:04 +0000 (02:00 +0000)
argument types for mem{set,cpy,move}. Character pointers, much like void
pointers, often point to generic "memory", so trying to check whether
they match the type of the argument to 'sizeof' (or other checks) is
unproductive and often results in false positives.

Nico, please review; does this miss any of the bugs you were trying to
find with this warning? The array test case you had should be caught by
the array-specific sizeof warning I think.

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

lib/Sema/SemaChecking.cpp
test/SemaCXX/warn-memset-bad-sizeof.cpp

index d45ebf9033d6730f567fafd95e02f2c899ab2628..945964fc351cb78545119c46f986b5ddd1759e77 100644 (file)
@@ -1866,7 +1866,9 @@ void Sema::CheckMemsetcpymoveArguments(const CallExpr *Call,
     if (const PointerType *DestPtrTy = DestTy->getAs<PointerType>()) {
       QualType PointeeTy = DestPtrTy->getPointeeType();
 
-      if (PointeeTy->isVoidType())
+      // Don't warn about void pointers or char pointers as both are often used
+      // for directly representing memory, regardless of its underlying type.
+      if (PointeeTy->isVoidType() || PointeeTy->isCharType())
         continue;
 
       // Catch "memset(p, 0, sizeof(p))" -- needs to be sizeof(*p).
index 9221590bd9eadf6104b4950a3954bf35fadaa6ce..167f05f3daff98775ba182bc3cc1448fcebc0464 100644 (file)
@@ -23,10 +23,11 @@ inline Dest bit_cast(const Source& source) {
 }
 
 // http://www.lysator.liu.se/c/c-faq/c-2.html#2-6
-void f(char fake_array[8], Mat m, const Foo& const_foo) {
+void f(Mat m, const Foo& const_foo) {
   S s;
   S* ps = &s;
   PS ps2 = &s;
+  char c = 42;
   char arr[5];
   char* parr[5];
   Foo foo;
@@ -42,8 +43,6 @@ void f(char fake_array[8], Mat m, const Foo& const_foo) {
       // expected-warning {{the argument to sizeof is pointer type 'typeof (ps2)' (aka 'S *'), expected 'S' to match first argument to 'memset'}}
   memset(ps2, 0, sizeof(PS));  // \
       // expected-warning {{the argument to sizeof is pointer type 'PS' (aka 'S *'), expected 'S' to match first argument to 'memset'}}
-  memset(fake_array, 0, sizeof(fake_array));  // \
-      // expected-warning {{the argument to sizeof is pointer type 'char *', expected 'char' to match first argument to 'memset'}}
 
   memcpy(&s, 0, sizeof(&s));  // \
       // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match first argument to 'memcpy'}}
@@ -69,6 +68,8 @@ void f(char fake_array[8], Mat m, const Foo& const_foo) {
   memcpy(&foo, &const_foo, sizeof(Foo));
   memcpy((void*)&s, 0, sizeof(&s));
   memcpy(0, (void*)&s, sizeof(&s));
+  memcpy(&parr[3], &c, sizeof(&c));
+  memcpy((char*)&parr[3], &c, sizeof(&c));
 
   CFooRef cfoo = foo;
   memcpy(&foo, &cfoo, sizeof(Foo));