Clang Project

clang_source_code/test/Frontend/noderef.c
1// RUN: %clang_cc1 -Wno-unused-value -verify %s
2
3#define NODEREF __attribute__((noderef))
4
5struct S {
6  int a;
7  int b;
8};
9
10struct 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
19int 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
24void func2(int x) {}
25
26int 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 2 {{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  // Nested struct access
67  struct S2 NODEREF *s2_noderef;    // expected-note 5 {{s2_noderef declared here}}
68  p = s2_noderef->a;  // ok since result is an array in a struct
69  p = s2_noderef->a2; // ok
70  p = s2_noderef->b;  // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
71  p = s2_noderef->b2; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
72  s = s2_noderef->s;  // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
73  s = s2_noderef->s2; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
74  p = s2_noderef->a + 1;
75
76  struct S2 *s2;
77  p = s2->a;
78  p = s2->a2;
79  p = s2->b;
80  p = s2->b2;
81  s = s2->s;
82  s = s2->s2;
83  &(*(*s2).s2).b;
84
85  // Subscript access
86  x = p[1];    // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
87  x = q[0][0]; // expected-warning{{dereferencing expression marked as 'noderef'}}
88  p2 = q2[0];  // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
89  p = q[*p];   // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
90  x = p[*p];   // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
91               // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
92
93  int NODEREF arr[10];    // expected-note 1 {{arr declared here}}
94  x = arr[1]; // expected-warning{{dereferencing arr; was declared with a 'noderef' type}}
95
96  int NODEREF *(arr2[10]);
97  int NODEREF *elem = *arr2;
98
99  int NODEREF(*arr3)[10];
100  elem = *arr3;
101
102  // Combinations between indirection, subscript, and member access
103  struct S2 NODEREF *s2_arr[10];
104  struct S2 NODEREF *s2_arr2[10][10];
105
106  p = s2_arr[1]->a;
107  p = s2_arr[1]->b; // expected-warning{{dereferencing expression marked as 'noderef'}}
108  int **bptr = &s2_arr[1]->b;
109
110  x = s2->s2->a;        // expected-warning{{dereferencing expression marked as 'noderef'}}
111  x = s2_noderef->a[1]; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
112  p = &s2_noderef->a[1];
113
114  // Casting to dereferenceable pointer
115  p2 = p;             // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
116  p2 = *q;            // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
117  p2 = q[0];          // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
118  s2 = s2_arr[1];     // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
119  s2 = s2_arr2[1][1]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
120  p2 = p, p2 = *q;    // expected-warning 2 {{casting to dereferenceable pointer removes 'noderef' attribute}}
121
122  // typedefs
123  typedef int NODEREF *ptr_t;
124  ptr_t ptr; // expected-note 2 {{ptr declared here}}
125  ptr_t *ptr2;
126  *ptr; // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}
127  *ptr2;
128  **ptr2; // expected-warning{{dereferencing expression marked as 'noderef'}}
129
130  typedef struct S2 NODEREF *s2_ptr_t;
131  s2_ptr_t s2_ptr; // expected-note 4 {{s2_ptr declared here}}
132  s2_ptr->a;       // ok since result is an array in a struct
133  s2_ptr->a2;      // ok
134  s2_ptr->b;       // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
135  s2_ptr->b2;      // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
136  s2_ptr->s;       // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
137  s2_ptr->s2;      // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
138  s2_ptr->a + 1;
139
140  typedef int(int_t);
141  typedef int_t NODEREF *(noderef_int_t);
142  typedef noderef_int_t *noderef_int_nested_t;
143  noderef_int_nested_t noderef_int_nested_ptr;
144  *noderef_int_nested_ptr;
145  **noderef_int_nested_ptr; // expected-warning{{dereferencing expression marked as 'noderef'}}
146
147  typedef int_t *(NODEREF noderef_int2_t);
148  typedef noderef_int2_t *noderef_int2_nested_t;
149  noderef_int2_nested_t noderef_int2_nested_ptr; // expected-note{{noderef_int2_nested_ptr declared here}}
150  *noderef_int2_nested_ptr;                      // expected-warning{{dereferencing noderef_int2_nested_ptr; was declared with a 'noderef' type}}
151
152  typedef int_t *(noderef_int3_t);
153  typedef noderef_int3_t(NODEREF(*(noderef_int3_nested_t)));
154  noderef_int3_nested_t noderef_int3_nested_ptr; // expected-note{{noderef_int3_nested_ptr declared here}}
155  *noderef_int3_nested_ptr;                      // expected-warning{{dereferencing noderef_int3_nested_ptr; was declared with a 'noderef' type}}
156
157  // Parentheses
158  (((*((p))))); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
159  (*(*(&(p)))); // expected-warning{{dereferencing expression marked as 'noderef'}}
160
161  (p[1]);      // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
162  (q[0]);      // ok
163  (q[0][0]);   // expected-warning{{dereferencing expression marked as 'noderef'}}
164  (q2[0]);     // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
165  (q[(*(p))]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
166  (p[(*(p))]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
167               // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
168
169  (*(ptr)); // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}
170  (*(ptr2));
171  (*(*(ptr2))); // expected-warning{{dereferencing expression marked as 'noderef'}}
172
173  // Functions
174  x = *(func(p)); // expected-warning{{dereferencing expression marked as 'noderef'}}
175
176  // Casting is ok
177  q = (int NODEREF **)&p;
178  q = (int NODEREF **)&p2;
179  q = &p;
180  q = &p2;
181  x = s2->s2->a; // expected-warning{{dereferencing expression marked as 'noderef'}}
182
183  // Other expressions
184  func2(*p);         // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
185  func2(*p + 1);     // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
186  func2(!*p);        // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
187  func2((x = *p));   // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
188  func2((char)(*p)); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
189
190  // Other statements
191  if (*p) {}          // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
192  else if (*p) {}     // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
193  switch (*p){}       // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
194  for (*p; *p; *p){}  // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
195                      // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
196                      // expected-warning@-2{{dereferencing p; was declared with a 'noderef' type}}
197  for (*p; *p;){}     // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
198                      // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
199  for (*p;; *p){}     // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
200                      // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
201  for (; *p; *p){}    // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
202                      // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
203  for (*p;;){}        // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
204  for (;*p;){}        // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
205  for (;;*p){}        // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
206  while (*p){}        // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
207  do {} while (*p);   // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
208  return *p;          // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
209}
210