Bug 1475882 - clang-analyzer: Enable clang-analyzer-unix.Malloc check. r?andi draft
authorChris Peterson <cpeterson@mozilla.com>
Sat, 14 Jul 2018 23:28:26 -0700
changeset 819044 cc7734e08afad52293a6b09a12abdee540ea7321
parent 819043 99547c607983003f1ce4a338ce8720d56a75f91f
child 819045 ae9282d1a7859b0be8af0e194536a1f7e5766da3
push id116421
push usercpeterson@mozilla.com
push dateTue, 17 Jul 2018 01:36:52 +0000
reviewersandi
bugs1475882
milestone63.0a1
Bug 1475882 - clang-analyzer: Enable clang-analyzer-unix.Malloc check. r?andi Check for memory leaks, double free, and use-after-free and offset problems involving malloc. There are currently no clang-analyzer-unix.Malloc warnings in mozilla-central! https://clang-analyzer.llvm.org/available_checks.html MozReview-Commit-ID: G32SlokD64O
tools/clang-tidy/config.yaml
tools/clang-tidy/test/clang-analyzer-unix.Malloc.cpp
tools/clang-tidy/test/clang-analyzer-unix.Malloc.json
tools/clang-tidy/test/structures.h
--- a/tools/clang-tidy/config.yaml
+++ b/tools/clang-tidy/config.yaml
@@ -29,16 +29,18 @@ clang_checkers:
   - name: clang-analyzer-security.insecureAPI.rand
     publish: !!bool no
   - name: clang-analyzer-security.insecureAPI.strcpy
     publish: !!bool no
   - name: clang-analyzer-security.insecureAPI.UncheckedReturn
     publish: !!bool yes
   - name: clang-analyzer-security.insecureAPI.vfork
     publish: !!bool yes
+  - name: clang-analyzer-unix.Malloc
+    publish: !!bool yes
   - name: clang-analyzer-unix.cstring.BadSizeArg
     publish: !!bool yes
   - name: clang-analyzer-unix.cstring.NullArg
     publish: !!bool yes
   - name: misc-argument-comment
     publish: !!bool yes
   - name: misc-assert-side-effect
     publish: !!bool yes
new file mode 100644
--- /dev/null
+++ b/tools/clang-tidy/test/clang-analyzer-unix.Malloc.cpp
@@ -0,0 +1,37 @@
+// https://clang-analyzer.llvm.org/available_checks.html
+
+#include "structures.h"
+
+void test_malloc()
+{
+  int *p = (int*) malloc(1);
+  free(p);
+  free(p); // warning: attempt to free released memory
+}
+
+void test_use_after_free()
+{
+  int *p = (int*) malloc(sizeof(int));
+  free(p);
+  *p = 1; // warning: use after free
+}
+
+void test_leak()
+{
+  int *p = (int*) malloc(1);
+  if (p)
+    return; // warning: memory is never released
+}
+
+void test_free_local()
+{
+  int a[] = { 1 };
+  free(a); // warning: argument is not allocated by malloc
+}
+
+void test_free_offset()
+{
+  int *p = (int*) malloc(sizeof(char));
+  p = p - 1;
+  free(p); // warning: argument to free() is offset by -4 bytes
+}
new file mode 100644
--- /dev/null
+++ b/tools/clang-tidy/test/clang-analyzer-unix.Malloc.json
@@ -0,0 +1,1 @@
+"[[\"warning\", \"Attempt to free released memory\", \"clang-analyzer-unix.Malloc\"], [\"warning\", \"Use of memory after it is freed\", \"clang-analyzer-unix.Malloc\"], [\"warning\", \"Potential leak of memory pointed to by 'p'\", \"clang-analyzer-unix.Malloc\"], [\"warning\", \"Argument to free() is the address of the local variable 'a', which is not memory allocated by malloc()\", \"clang-analyzer-unix.Malloc\"], [\"warning\", \"Argument to free() is offset by -4 bytes from the start of memory allocated by malloc()\", \"clang-analyzer-unix.Malloc\"]]"
--- a/tools/clang-tidy/test/structures.h
+++ b/tools/clang-tidy/test/structures.h
@@ -85,8 +85,11 @@ pid_t vfork(void);
 int abort() { return 0; }
 
 #define assert(x)                                                              \
   if (!(x))                                                                    \
   (void)abort()
 
 std::size_t strlen(const char *s);
 char *strncat(char *s1, const char *s2, std::size_t n);
+
+void free(void *ptr);
+void *malloc(std::size_t size);