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