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