diff options
Diffstat (limited to 'clang/test/Analysis/array-struct.c')
-rw-r--r-- | clang/test/Analysis/array-struct.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/clang/test/Analysis/array-struct.c b/clang/test/Analysis/array-struct.c new file mode 100644 index 0000000..c5bdb86 --- /dev/null +++ b/clang/test/Analysis/array-struct.c @@ -0,0 +1,178 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core.CastToStruct -analyzer-store=region -analyzer-constraints=basic -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core.CastToStruct -analyzer-store=region -analyzer-constraints=range -verify %s + +struct s { + int data; + int data_array[10]; +}; + +typedef struct { + int data; +} STYPE; + +void g(char *p); +void g1(struct s* p); + +// Array to pointer conversion. Array in the struct field. +void f(void) { + int a[10]; + int (*p)[10]; + p = &a; + (*p)[3] = 1; + + struct s d; + struct s *q; + q = &d; + q->data = 3; + d.data_array[9] = 17; +} + +// StringLiteral in lvalue context and pointer to array type. +// p: ElementRegion, q: StringRegion +void f2() { + char *p = "/usr/local"; + char (*q)[4]; + q = &"abc"; +} + +// Typedef'ed struct definition. +void f3() { + STYPE s; +} + +// Initialize array with InitExprList. +void f4() { + int a[] = { 1, 2, 3}; + int b[3] = { 1, 2 }; + struct s c[] = {{1,{1}}}; +} + +// Struct variable in lvalue context. +// Assign UnknownVal to the whole struct. +void f5() { + struct s data; + g1(&data); +} + +// AllocaRegion test. +void f6() { + char *p; + p = __builtin_alloca(10); + g(p); + char c = *p; + p[1] = 'a'; + // Test if RegionStore::EvalBinOp converts the alloca region to element + // region. + p += 2; +} + +struct s2; + +void g2(struct s2 *p); + +// Incomplete struct pointer used as function argument. +void f7() { + struct s2 *p = __builtin_alloca(10); + g2(p); +} + +// sizeof() is unsigned while -1 is signed in array index. +void f8() { + int a[10]; + a[sizeof(a)/sizeof(int) - 1] = 1; // no-warning +} + +// Initialization of struct array elements. +void f9() { + struct s a[10]; +} + +// Initializing array with string literal. +void f10() { + char a1[4] = "abc"; + char a3[6] = "abc"; +} + +// Retrieve the default value of element/field region. +void f11() { + struct s a; + g1(&a); + if (a.data == 0) // no-warning + a.data = 1; +} + +// Convert unsigned offset to signed when creating ElementRegion from +// SymbolicRegion. +void f12(int *list) { + unsigned i = 0; + list[i] = 1; +} + +struct s1 { + struct s2 { + int d; + } e; +}; + +// The binding of a.e.d should not be removed. Test recursive subregion map +// building: a->e, e->d. Only then 'a' could be added to live region roots. +void f13(double timeout) { + struct s1 a; + a.e.d = (int) timeout; + if (a.e.d == 10) + a.e.d = 4; +} + +struct s3 { + int a[2]; +}; + +static struct s3 opt; + +// Test if the embedded array is retrieved correctly. +void f14() { + struct s3 my_opt = opt; +} + +void bar(int*); + +// Test if the array is correctly invalidated. +void f15() { + int a[10]; + bar(a); + if (a[1]) // no-warning + (void)1; +} + +struct s3 p[1]; + +// Code from postgresql. +// Current cast logic of region store mistakenly leaves the final result region +// an ElementRegion of type 'char'. Then load a nonloc::SymbolVal from it and +// assigns to 'a'. +void f16(struct s3 *p) { + struct s3 a = *((struct s3*) ((char*) &p[0])); // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption.}} +} + +void inv(struct s1 *); + +// Invalidate the struct field. +void f17() { + struct s1 t; + int x; + inv(&t); + if (t.e.d) + x = 1; +} + +void read(char*); + +void f18() { + char *q; + char *p = (char *) __builtin_alloca(10); + read(p); + q = p; + q++; + if (*q) { // no-warning + } +} |