• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)17 void 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()32 void f2() {
33   char *p = "/usr/local";
34   char (*q)[4];
35   q = &"abc";
36 }
37 
38 // Typedef'ed struct definition.
f3()39 void f3() {
40   STYPE s;
41 }
42 
43 // Initialize array with InitExprList.
f4()44 void 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()52 void f5() {
53   struct s data;
54   g1(&data);
55 }
56 
57 // AllocaRegion test.
f6()58 void 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()74 void 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()80 void f8() {
81   int a[10];
82   a[sizeof(a)/sizeof(int) - 1] = 1; // no-warning
83 }
84 
85 // Initialization of struct array elements.
f9()86 void f9() {
87   struct s a[10];
88 }
89 
90 // Initializing array with string literal.
f10()91 void f10() {
92   char a1[4] = "abc";
93   char a3[6] = "abc";
94 }
95 
96 // Retrieve the default value of element/field region.
f11()97 void 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)106 void 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)119 void 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()133 void f14() {
134   struct s3 my_opt = opt;
135 }
136 
137 void bar(int*);
138 
139 // Test if the array is correctly invalidated.
f15()140 void 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)153 void 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()160 void 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()170 void 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