[analyzer] Tweak MallocSizeOfChecker to not warn when using sizeof(void*) to allocate...
authorTed Kremenek <kremenek@apple.com>
Sun, 19 Oct 2014 07:30:55 +0000 (07:30 +0000)
committerTed Kremenek <kremenek@apple.com>
Sun, 19 Oct 2014 07:30:55 +0000 (07:30 +0000)
This suppresses a common false positive when analyzing libc++.

Along the way, introduce some tests to show this checker actually
works with C++ static_cast<>.

llvm-svn: 220160

clang/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
clang/test/Analysis/malloc-sizeof.cpp [new file with mode: 0644]

index 4a50d93..296aec6 100644 (file)
@@ -137,6 +137,10 @@ public:
 // Determine if the pointee and sizeof types are compatible.  Here
 // we ignore constness of pointer types.
 static bool typesCompatible(ASTContext &C, QualType A, QualType B) {
+  // sizeof(void*) is compatible with any other pointer.
+  if (B->isVoidPointerType() && A->getAs<PointerType>())
+    return true;
+
   while (true) {
     A = A.getCanonicalType();
     B = B.getCanonicalType();
diff --git a/clang/test/Analysis/malloc-sizeof.cpp b/clang/test/Analysis/malloc-sizeof.cpp
new file mode 100644 (file)
index 0000000..8589975
--- /dev/null
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=unix.MallocSizeof -verify %s
+
+#include <stddef.h>
+
+void *malloc(size_t size);
+void *calloc(size_t nmemb, size_t size);
+void *realloc(void *ptr, size_t size);
+void free(void *ptr);
+
+struct A {};
+struct B {};
+
+void foo(unsigned int unsignedInt, unsigned int readSize) {
+  // Sanity check the checker is working as expected.
+  A* a = static_cast<A*>(malloc(sizeof(int))); // expected-warning {{Result of 'malloc' is converted to a pointer of type 'struct A', which is incompatible with sizeof operand type 'int'}}
+  free(a);
+}
+
+void bar() {
+  A *x = static_cast<A*>(calloc(10, sizeof(void*))); // expected-warning {{Result of 'calloc' is converted to a pointer of type 'struct A', which is incompatible with sizeof operand type 'void *'}}
+  // sizeof(void*) is compatible with any pointer.
+  A **y = static_cast<A**>(calloc(10, sizeof(void*))); // no-warning
+  free(x);
+  free(y);
+}
+