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