diff options
author | Jordan Rose <jordan_rose@apple.com> | 2014-03-26 17:05:46 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2014-03-26 17:05:46 +0000 |
commit | 6b33c6f2349f74f0a70d5447e2c3eb0913aba902 (patch) | |
tree | c07ff98962c8fc619c7d6ac5ee0b40eec0871894 /clang/test/Analysis/kmalloc-linux.c | |
parent | 5df175cec8ed9ae694fd75ec39c25e9d2eb693f1 (diff) | |
download | bcm5719-llvm-6b33c6f2349f74f0a70d5447e2c3eb0913aba902.tar.gz bcm5719-llvm-6b33c6f2349f74f0a70d5447e2c3eb0913aba902.zip |
[analyzer] Handle the M_ZERO and __GFP_ZERO flags in kernel mallocs.
Add M_ZERO awareness to malloc() static analysis in Clang for FreeBSD,
NetBSD, and OpenBSD in a similar fashion to O_CREAT for open(2).
These systems have a three-argument malloc() in the kernel where the
third argument contains flags; the M_ZERO flag will zero-initialize the
allocated buffer.
This should reduce the number of false positives when running static
analysis on BSD kernels.
Additionally, add kmalloc() (Linux kernel malloc()) and treat __GFP_ZERO
like M_ZERO on Linux.
Future work involves a better method of checking for named flags without
hardcoding values.
Patch by Conrad Meyer, with minor modifications by me.
llvm-svn: 204832
Diffstat (limited to 'clang/test/Analysis/kmalloc-linux.c')
-rw-r--r-- | clang/test/Analysis/kmalloc-linux.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/clang/test/Analysis/kmalloc-linux.c b/clang/test/Analysis/kmalloc-linux.c new file mode 100644 index 00000000000..87c1107a102 --- /dev/null +++ b/clang/test/Analysis/kmalloc-linux.c @@ -0,0 +1,58 @@ +// RUN: %clang -target x86_64-unknown-linux --analyze %s + +#include "Inputs/system-header-simulator.h" + +#define __GFP_ZERO 0x8000 +#define NULL ((void *)0) + +void *kmalloc(size_t, int); + +struct test { +}; + +void foo(struct test *); + +void test_zeroed() { + struct test **list, *t; + int i; + + list = kmalloc(sizeof(*list) * 10, __GFP_ZERO); + if (list == NULL) + return; + + for (i = 0; i < 10; i++) { + t = list[i]; + foo(t); + } + free(list); // no-warning +} + +void test_nonzero() { + struct test **list, *t; + int i; + + list = kmalloc(sizeof(*list) * 10, 0); + if (list == NULL) + return; + + for (i = 0; i < 10; i++) { + t = list[i]; // expected-warning{{undefined}} + foo(t); + } + free(list); +} + +void test_indeterminate(int flags) { + struct test **list, *t; + int i; + + list = kmalloc(sizeof(*list) * 10, flags); + if (list == NULL) + return; + + for (i = 0; i < 10; i++) { + t = list[i]; // expected-warning{{undefined}} + foo(t); + } + free(list); +} |