1 // RUN: %clang_cc1 -Wno-unused-value -verify %s
2
3 #define NODEREF __attribute__((noderef))
4
5 struct S {
6 int a;
7 int b;
8 };
9
10 struct S2 {
11 int a[2];
12 int NODEREF a2[2];
13 int *b;
14 int NODEREF *b2;
15 struct S *s;
16 struct S NODEREF *s2;
17 };
18
func(int NODEREF * arg)19 int NODEREF *func(int NODEREF *arg) { // expected-note{{arg declared here}}
20 int y = *arg; // expected-warning{{dereferencing arg; was declared with a 'noderef' type}}
21 return arg;
22 }
23
func2(int x)24 void func2(int x) {}
25
test()26 int test() {
27 int NODEREF *p; // expected-note 34 {{p declared here}}
28 int *p2;
29
30 int x = *p; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
31 x = *((int NODEREF *)p2); // expected-warning{{dereferencing expression marked as 'noderef'}}
32
33 int NODEREF **q;
34 int *NODEREF *q2; // expected-note 4 {{q2 declared here}}
35
36 // Indirection
37 x = **q; // expected-warning{{dereferencing expression marked as 'noderef'}}
38 p2 = *q2; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
39
40 **q; // expected-warning{{dereferencing expression marked as 'noderef'}}
41
42 p = *&*q;
43 p = **&q;
44 q = &**&q;
45 p = &*p;
46 p = *&p;
47 p = &(*p);
48 p = *(&p);
49 x = **&p; // expected-warning{{dereferencing expression marked as 'noderef'}}
50
51 *p = 2; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
52 *q = p; // ok
53 **q = 2; // expected-warning{{dereferencing expression marked as 'noderef'}}
54 *q2 = p2; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
55
56 p = p + 1;
57 p = &*(p + 1);
58
59 // Struct member access
60 struct S NODEREF *s; // expected-note 3 {{s declared here}}
61 x = s->a; // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
62 x = (*s).b; // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
63 p = &s->a;
64 p = &(*s).b;
65
66 // Most things in sizeof() can't actually access memory
67 x = sizeof(s->a); // ok
68 x = sizeof(*s); // ok
69 x = sizeof(s[0]); // ok
70 x = sizeof(s->a + (s->b)); // ok
71 x = sizeof(int[++s->a]); // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
72
73 // Struct member access should carry NoDeref type information through to an
74 // enclosing AddrOf.
75 p2 = &s->a; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
76 p2 = &(*s).a; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
77 x = *&s->a; // expected-warning{{dereferencing expression marked as 'noderef'}}
78
79 // Nested struct access
80 struct S2 NODEREF *s2_noderef; // expected-note 5 {{s2_noderef declared here}}
81 p = s2_noderef->a; // ok since result is an array in a struct
82 p = (*s2_noderef).a; // ok since result is an array in a struct
83 p = s2_noderef->a2; // ok
84 p = s2_noderef->b; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
85 p = s2_noderef->b2; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
86 s = s2_noderef->s; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
87 s = s2_noderef->s2; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
88 p = s2_noderef->a + 1;
89
90 struct S2 *s2;
91 p = s2->a;
92 p = s2->a2;
93 p = s2->b;
94 p = s2->b2;
95 s = s2->s;
96 s = s2->s2;
97 &(*(*s2).s2).b;
98
99 // Subscript access
100 x = p[1]; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
101 x = q[0][0]; // expected-warning{{dereferencing expression marked as 'noderef'}}
102 p2 = q2[0]; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
103 p = q[*p]; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
104 x = p[*p]; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
105 // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
106
107 int NODEREF arr[10]; // expected-note 1 {{arr declared here}}
108 x = arr[1]; // expected-warning{{dereferencing arr; was declared with a 'noderef' type}}
109
110 int NODEREF *(arr2[10]);
111 int NODEREF *elem = *arr2;
112
113 int NODEREF(*arr3)[10];
114 elem = *arr3;
115
116 // Combinations between indirection, subscript, and member access
117 struct S2 NODEREF *s2_arr[10];
118 struct S2 NODEREF *s2_arr2[10][10];
119
120 p = s2_arr[1]->a;
121 p = s2_arr[1]->b; // expected-warning{{dereferencing expression marked as 'noderef'}}
122 int *NODEREF *bptr = &s2_arr[1]->b;
123
124 x = s2->s2->a; // expected-warning{{dereferencing expression marked as 'noderef'}}
125 x = s2_noderef->a[1]; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
126 p = &s2_noderef->a[1];
127
128 // Casting to dereferenceable pointer
129 p2 = p; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
130 p2 = *q; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
131 p2 = q[0]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
132 s2 = s2_arr[1]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
133 s2 = s2_arr2[1][1]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
134 p2 = p, p2 = *q; // expected-warning 2 {{casting to dereferenceable pointer removes 'noderef' attribute}}
135
136 // typedefs
137 typedef int NODEREF *ptr_t;
138 ptr_t ptr; // expected-note 2 {{ptr declared here}}
139 ptr_t *ptr2;
140 *ptr; // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}
141 *ptr2;
142 **ptr2; // expected-warning{{dereferencing expression marked as 'noderef'}}
143
144 typedef struct S2 NODEREF *s2_ptr_t;
145 s2_ptr_t s2_ptr; // expected-note 4 {{s2_ptr declared here}}
146 s2_ptr->a; // ok since result is an array in a struct
147 s2_ptr->a2; // ok
148 s2_ptr->b; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
149 s2_ptr->b2; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
150 s2_ptr->s; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
151 s2_ptr->s2; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
152 s2_ptr->a + 1;
153
154 typedef int(int_t);
155 typedef int_t NODEREF *(noderef_int_t);
156 typedef noderef_int_t *noderef_int_nested_t;
157 noderef_int_nested_t noderef_int_nested_ptr;
158 *noderef_int_nested_ptr;
159 **noderef_int_nested_ptr; // expected-warning{{dereferencing expression marked as 'noderef'}}
160
161 typedef int_t *(NODEREF noderef_int2_t);
162 typedef noderef_int2_t *noderef_int2_nested_t;
163 noderef_int2_nested_t noderef_int2_nested_ptr; // expected-note{{noderef_int2_nested_ptr declared here}}
164 *noderef_int2_nested_ptr; // expected-warning{{dereferencing noderef_int2_nested_ptr; was declared with a 'noderef' type}}
165
166 typedef int_t *(noderef_int3_t);
167 typedef noderef_int3_t(NODEREF(*(noderef_int3_nested_t)));
168 noderef_int3_nested_t noderef_int3_nested_ptr; // expected-note{{noderef_int3_nested_ptr declared here}}
169 *noderef_int3_nested_ptr; // expected-warning{{dereferencing noderef_int3_nested_ptr; was declared with a 'noderef' type}}
170
171 // Parentheses
172 (((*((p))))); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
173 (*(*(&(p)))); // expected-warning{{dereferencing expression marked as 'noderef'}}
174
175 (p[1]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
176 (q[0]); // ok
177 (q[0][0]); // expected-warning{{dereferencing expression marked as 'noderef'}}
178 (q2[0]); // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
179 (q[(*(p))]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
180 (p[(*(p))]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
181 // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
182
183 (*(ptr)); // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}
184 (*(ptr2));
185 (*(*(ptr2))); // expected-warning{{dereferencing expression marked as 'noderef'}}
186
187 // Functions
188 x = *(func(p)); // expected-warning{{dereferencing expression marked as 'noderef'}}
189
190 // Casting is ok
191 q = (int NODEREF **)&p;
192 q = (int NODEREF **)&p2;
193 q = &p;
194 q = &p2;
195 x = s2->s2->a; // expected-warning{{dereferencing expression marked as 'noderef'}}
196
197 // Other expressions
198 func2(*p); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
199 func2(*p + 1); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
200 func2(!*p); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
201 func2((x = *p)); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
202 func2((char)(*p)); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
203
204 // Other statements
205 if (*p) {} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
206 else if (*p) {} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
207 switch (*p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
208 for (*p; *p; *p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
209 // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
210 // expected-warning@-2{{dereferencing p; was declared with a 'noderef' type}}
211 for (*p; *p;){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
212 // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
213 for (*p;; *p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
214 // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
215 for (; *p; *p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
216 // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
217 for (*p;;){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
218 for (;*p;){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
219 for (;;*p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
220 while (*p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
221 do {} while (*p); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
222 return *p; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
223 }
224