1// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.CastToStruct -analyzer-store=region -analyzer-constraints=range -verify %s 2 3struct s { 4 int data; 5 int data_array[10]; 6}; 7 8typedef struct { 9 int data; 10} STYPE; 11 12void g(char *p); 13void g1(struct s* p); 14 15// Array to pointer conversion. Array in the struct field. 16void f(void) { 17 int a[10]; 18 int (*p)[10]; 19 p = &a; 20 (*p)[3] = 1; 21 22 struct s d; 23 struct s *q; 24 q = &d; 25 q->data = 3; 26 d.data_array[9] = 17; 27} 28 29// StringLiteral in lvalue context and pointer to array type. 30// p: ElementRegion, q: StringRegion 31void f2() { 32 char *p = "/usr/local"; 33 char (*q)[4]; 34 q = &"abc"; 35} 36 37// Typedef'ed struct definition. 38void f3() { 39 STYPE s; 40} 41 42// Initialize array with InitExprList. 43void f4() { 44 int a[] = { 1, 2, 3}; 45 int b[3] = { 1, 2 }; 46 struct s c[] = {{1,{1}}}; 47} 48 49// Struct variable in lvalue context. 50// Assign UnknownVal to the whole struct. 51void f5() { 52 struct s data; 53 g1(&data); 54} 55 56// AllocaRegion test. 57void f6() { 58 char *p; 59 p = __builtin_alloca(10); 60 g(p); 61 char c = *p; 62 p[1] = 'a'; 63 // Test if RegionStore::EvalBinOp converts the alloca region to element 64 // region. 65 p += 2; 66} 67 68struct s2; 69 70void g2(struct s2 *p); 71 72// Incomplete struct pointer used as function argument. 73void f7() { 74 struct s2 *p = __builtin_alloca(10); 75 g2(p); 76} 77 78// sizeof() is unsigned while -1 is signed in array index. 79void f8() { 80 int a[10]; 81 a[sizeof(a)/sizeof(int) - 1] = 1; // no-warning 82} 83 84// Initialization of struct array elements. 85void f9() { 86 struct s a[10]; 87} 88 89// Initializing array with string literal. 90void f10() { 91 char a1[4] = "abc"; 92 char a3[6] = "abc"; 93} 94 95// Retrieve the default value of element/field region. 96void f11() { 97 struct s a; 98 g1(&a); 99 if (a.data == 0) // no-warning 100 a.data = 1; 101} 102 103// Convert unsigned offset to signed when creating ElementRegion from 104// SymbolicRegion. 105void f12(int *list) { 106 unsigned i = 0; 107 list[i] = 1; 108} 109 110struct s1 { 111 struct s2 { 112 int d; 113 } e; 114}; 115 116// The binding of a.e.d should not be removed. Test recursive subregion map 117// building: a->e, e->d. Only then 'a' could be added to live region roots. 118void f13(double timeout) { 119 struct s1 a; 120 a.e.d = (int) timeout; 121 if (a.e.d == 10) 122 a.e.d = 4; 123} 124 125struct s3 { 126 int a[2]; 127}; 128 129static struct s3 opt; 130 131// Test if the embedded array is retrieved correctly. 132void f14() { 133 struct s3 my_opt = opt; 134} 135 136void bar(int*); 137 138// Test if the array is correctly invalidated. 139void f15() { 140 int a[10]; 141 bar(a); 142 if (a[1]) // no-warning 143 (void)1; 144} 145 146struct s3 p[1]; 147 148// Code from postgresql. 149// Current cast logic of region store mistakenly leaves the final result region 150// an ElementRegion of type 'char'. Then load a nonloc::SymbolVal from it and 151// assigns to 'a'. 152void f16(struct s3 *p) { 153 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}} 154} 155 156void inv(struct s1 *); 157 158// Invalidate the struct field. 159void f17() { 160 struct s1 t; 161 int x; 162 inv(&t); 163 if (t.e.d) 164 x = 1; 165} 166 167void read(char*); 168 169void f18() { 170 char *q; 171 char *p = (char *) __builtin_alloca(10); 172 read(p); 173 q = p; 174 q++; 175 if (*q) { // no-warning 176 } 177} 178