diff options
author | Jordan Rose <jordan_rose@apple.com> | 2014-02-18 17:06:30 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2014-02-18 17:06:30 +0000 |
commit | 97d2c9cae777cfc042bae9c4f7d2cc7705778491 (patch) | |
tree | 08c9b98f57373b8f6e646eb93687d6145e56eff0 /clang/test | |
parent | 5cc5cd907d52e65b7f0b61f40c4b6b08d866c969 (diff) | |
download | bcm5719-llvm-97d2c9cae777cfc042bae9c4f7d2cc7705778491.tar.gz bcm5719-llvm-97d2c9cae777cfc042bae9c4f7d2cc7705778491.zip |
[analyzer] Teach CastSizeChecker about flexible array members.
...as well as fake flexible array members: structs that end in arrays with
length 0 or 1.
Patch by Daniel Fahlgren!
llvm-svn: 201583
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/Analysis/malloc.c | 216 | ||||
-rw-r--r-- | clang/test/Analysis/no-outofbounds.c | 4 |
2 files changed, 218 insertions, 2 deletions
diff --git a/clang/test/Analysis/malloc.c b/clang/test/Analysis/malloc.c index 58d40a31a83..9c08bbcb1c0 100644 --- a/clang/test/Analysis/malloc.c +++ b/clang/test/Analysis/malloc.c @@ -270,6 +270,222 @@ void PR7217() { buf[1] = 'c'; // not crash } +void cast_emtpy_struct() { + struct st { + }; + + struct st *s = malloc(sizeof(struct st)); // no-warning + free(s); +} + +void cast_struct_1() { + struct st { + int i[100]; + char j[]; + }; + + struct st *s = malloc(sizeof(struct st)); // no-warning + free(s); +} + +void cast_struct_2() { + struct st { + int i[100]; + char j[0]; + }; + + struct st *s = malloc(sizeof(struct st)); // no-warning + free(s); +} + +void cast_struct_3() { + struct st { + int i[100]; + char j[1]; + }; + + struct st *s = malloc(sizeof(struct st)); // no-warning + free(s); +} + +void cast_struct_4() { + struct st { + int i[100]; + char j[2]; + }; + + struct st *s = malloc(sizeof(struct st)); // no-warning + free(s); +} + +void cast_struct_5() { + struct st { + char i[200]; + char j[1]; + }; + + struct st *s = malloc(sizeof(struct st) - sizeof(char)); // no-warning + free(s); +} + +void cast_struct_warn_1() { + struct st { + int i[100]; + char j[2]; + }; + + struct st *s = malloc(sizeof(struct st) + 2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} + free(s); +} + +void cast_struct_warn_2() { + struct st { + int i[100]; + char j[2]; + }; + + struct st *s = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} + free(s); +} + +void cast_struct_flex_array_1() { + struct st { + int i[100]; + char j[]; + }; + + struct st *s = malloc(sizeof(struct st) + 3); // no-warning + free(s); +} + +void cast_struct_flex_array_2() { + struct st { + int i[100]; + char j[0]; + }; + + struct st *s = malloc(sizeof(struct st) + 3); // no-warning + free(s); +} + +void cast_struct_flex_array_3() { + struct st { + int i[100]; + char j[1]; + }; + + struct st *s = malloc(sizeof(struct st) + 3); // no-warning + free(s); +} + +void cast_struct_flex_array_4() { + struct foo { + char f[32]; + }; + struct st { + char i[100]; + struct foo data[]; + }; + + struct st *s = malloc(sizeof(struct st) + 3 * sizeof(struct foo)); // no-warning + free(s); +} + +void cast_struct_flex_array_5() { + struct foo { + char f[32]; + }; + struct st { + char i[100]; + struct foo data[0]; + }; + + struct st *s = malloc(sizeof(struct st) + 3 * sizeof(struct foo)); // no-warning + free(s); +} + +void cast_struct_flex_array_6() { + struct foo { + char f[32]; + }; + struct st { + char i[100]; + struct foo data[1]; + }; + + struct st *s = malloc(sizeof(struct st) + 3 * sizeof(struct foo)); // no-warning + free(s); +} + +void cast_struct_flex_array_warn_1() { + struct foo { + char f[32]; + }; + struct st { + char i[100]; + struct foo data[]; + }; + + struct st *s = malloc(3 * sizeof(struct st) + 3 * sizeof(struct foo)); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} + free(s); +} + +void cast_struct_flex_array_warn_2() { + struct foo { + char f[32]; + }; + struct st { + char i[100]; + struct foo data[0]; + }; + + struct st *s = malloc(3 * sizeof(struct st) + 3 * sizeof(struct foo)); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} + free(s); +} + +void cast_struct_flex_array_warn_3() { + struct foo { + char f[32]; + }; + struct st { + char i[100]; + struct foo data[1]; + }; + + struct st *s = malloc(3 * sizeof(struct st) + 3 * sizeof(struct foo)); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} + free(s); +} + +void cast_struct_flex_array_warn_4() { + struct st { + int i[100]; + int j[]; + }; + + struct st *s = malloc(sizeof(struct st) + 3); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} + free(s); +} + +void cast_struct_flex_array_warn_5() { + struct st { + int i[100]; + int j[0]; + }; + + struct st *s = malloc(sizeof(struct st) + 3); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} + free(s); +} + +void cast_struct_flex_array_warn_6() { + struct st { + int i[100]; + int j[1]; + }; + + struct st *s = malloc(sizeof(struct st) + 3); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} + free(s); +} + void mallocCastToVoid() { void *p = malloc(2); const void *cp = p; // not crash diff --git a/clang/test/Analysis/no-outofbounds.c b/clang/test/Analysis/no-outofbounds.c index 84f86d79bd5..d4012794d5c 100644 --- a/clang/test/Analysis/no-outofbounds.c +++ b/clang/test/Analysis/no-outofbounds.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,alpha.unix,alpha.security.ArrayBound -analyzer-store=region -verify %s +// expected-no-diagnostics //===----------------------------------------------------------------------===// // This file tests cases where we should not flag out-of-bounds warnings. @@ -24,8 +25,7 @@ void free(void *); void field() { struct vec { size_t len; int data[0]; }; - // FIXME: Not warn for this. - struct vec *a = malloc(sizeof(struct vec) + 10); // expected-warning {{Cast a region whose size is not a multiple of the destination type size}} + struct vec *a = malloc(sizeof(struct vec) + 10*sizeof(int)); a->len = 10; a->data[1] = 5; // no-warning free(a); |