xref: /minix3/external/bsd/llvm/dist/clang/test/Analysis/array-struct.c (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
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 Sambuc void 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 Sambuc void 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 Sambuc void f3() {
39*f4a2713aSLionel Sambuc   STYPE s;
40*f4a2713aSLionel Sambuc }
41*f4a2713aSLionel Sambuc 
42*f4a2713aSLionel Sambuc // Initialize array with InitExprList.
f4()43*f4a2713aSLionel Sambuc void 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 Sambuc void 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 Sambuc void 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 Sambuc void 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 Sambuc void 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 Sambuc void 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 Sambuc void 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 Sambuc void 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 Sambuc void 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 Sambuc void 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 Sambuc void 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 Sambuc void 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 Sambuc void 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 Sambuc void 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 Sambuc void 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 Sambuc int 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