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