1 // RUN: %clang_cc1 -Wno-unused-value -verify %s
3 #define NODEREF __attribute__((noderef))
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}}
27 int NODEREF
*p
; // expected-note 34 {{p declared here}}
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'}}
34 int *NODEREF
*q2
; // expected-note 4 {{q2 declared here}}
37 x
= **q
; // expected-warning{{dereferencing expression marked as 'noderef'}}
38 p2
= *q2
; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
40 **q
; // expected-warning{{dereferencing expression marked as 'noderef'}}
49 x
= **&p
; // expected-warning{{dereferencing expression marked as 'noderef'}}
51 *p
= 2; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
53 **q
= 2; // expected-warning{{dereferencing expression marked as 'noderef'}}
54 *q2
= p2
; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
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}}
66 // Most things in sizeof() can't actually access memory
67 x
= sizeof(s
->a
); // 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}}
73 // Struct member access should carry NoDeref type information through to an
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'}}
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;
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}}
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}}
110 int NODEREF
*(arr2
[10]);
111 int NODEREF
*elem
= *arr2
;
113 int NODEREF(*arr3
)[10];
116 // Combinations between indirection, subscript, and member access
117 struct S2 NODEREF
*s2_arr
[10];
118 struct S2 NODEREF
*s2_arr2
[10][10];
121 p
= s2_arr
[1]->b
; // expected-warning{{dereferencing expression marked as 'noderef'}}
122 int *NODEREF
*bptr
= &s2_arr
[1]->b
;
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];
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}}
137 typedef int NODEREF
*ptr_t
;
138 ptr_t ptr
; // expected-note 2 {{ptr declared here}}
140 *ptr
; // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}
142 **ptr2
; // expected-warning{{dereferencing expression marked as 'noderef'}}
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
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}}
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'}}
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}}
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}}
172 (((*((p
))))); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
173 (*(*(&(p
)))); // expected-warning{{dereferencing expression marked as 'noderef'}}
175 (p
[1]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
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}}
183 (*(ptr
)); // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}
185 (*(*(ptr2
))); // expected-warning{{dereferencing expression marked as 'noderef'}}
188 x
= *(func(p
)); // expected-warning{{dereferencing expression marked as 'noderef'}}
191 q
= (int NODEREF
**)&p
;
192 q
= (int NODEREF
**)&p2
;
195 x
= s2
->s2
->a
; // expected-warning{{dereferencing expression marked as 'noderef'}}
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}}
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}}
225 // FIXME: Currently, [[]] syntax does not work for the `noderef` atribute.
226 // For the time being, test that we consistently diagnose the attribute as
228 // For details see https://github.com/llvm/llvm-project/issues/55790
229 void test_standard_syntax() {
230 [[clang::noderef
]] int i
; // expected-warning {{'noderef' attribute ignored}}
232 [[clang::noderef
]] int *p1
; // expected-warning {{'noderef' attribute ignored}}
235 int *p2
[[clang::noderef
]]; // expected-warning {{'noderef' attribute ignored}}
238 int * [[clang::noderef
]] p3
; // expected-warning {{'noderef' attribute ignored}}
242 [[clang::noderef
]] IntPtr p4
; // expected-warning {{'noderef' attribute ignored}}