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