123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- // RUN: %clang_cc1 -Wno-unused-value -verify %s
- #define NODEREF __attribute__((noderef))
- struct S {
- int a;
- int b;
- };
- struct S2 {
- int a[2];
- int NODEREF a2[2];
- int *b;
- int NODEREF *b2;
- struct S *s;
- struct S NODEREF *s2;
- };
- int NODEREF *func(int NODEREF *arg) { // expected-note{{arg declared here}}
- int y = *arg; // expected-warning{{dereferencing arg; was declared with a 'noderef' type}}
- return arg;
- }
- void func2(int x) {}
- int test() {
- int NODEREF *p; // expected-note 34 {{p declared here}}
- int *p2;
- int x = *p; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- x = *((int NODEREF *)p2); // expected-warning{{dereferencing expression marked as 'noderef'}}
- int NODEREF **q;
- int *NODEREF *q2; // expected-note 4 {{q2 declared here}}
- // Indirection
- x = **q; // expected-warning{{dereferencing expression marked as 'noderef'}}
- p2 = *q2; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
- **q; // expected-warning{{dereferencing expression marked as 'noderef'}}
- p = *&*q;
- p = **&q;
- q = &**&q;
- p = &*p;
- p = *&p;
- p = &(*p);
- p = *(&p);
- x = **&p; // expected-warning{{dereferencing expression marked as 'noderef'}}
- *p = 2; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- *q = p; // ok
- **q = 2; // expected-warning{{dereferencing expression marked as 'noderef'}}
- *q2 = p2; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
- p = p + 1;
- p = &*(p + 1);
- // Struct member access
- struct S NODEREF *s; // expected-note 2 {{s declared here}}
- x = s->a; // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
- x = (*s).b; // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
- p = &s->a;
- p = &(*s).b;
- // Nested struct access
- struct S2 NODEREF *s2_noderef; // expected-note 5 {{s2_noderef declared here}}
- p = s2_noderef->a; // ok since result is an array in a struct
- p = s2_noderef->a2; // ok
- p = s2_noderef->b; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
- p = s2_noderef->b2; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
- s = s2_noderef->s; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
- s = s2_noderef->s2; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
- p = s2_noderef->a + 1;
- struct S2 *s2;
- p = s2->a;
- p = s2->a2;
- p = s2->b;
- p = s2->b2;
- s = s2->s;
- s = s2->s2;
- &(*(*s2).s2).b;
- // Subscript access
- x = p[1]; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- x = q[0][0]; // expected-warning{{dereferencing expression marked as 'noderef'}}
- p2 = q2[0]; // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
- p = q[*p]; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- x = p[*p]; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
- int NODEREF arr[10]; // expected-note 1 {{arr declared here}}
- x = arr[1]; // expected-warning{{dereferencing arr; was declared with a 'noderef' type}}
- int NODEREF *(arr2[10]);
- int NODEREF *elem = *arr2;
- int NODEREF(*arr3)[10];
- elem = *arr3;
- // Combinations between indirection, subscript, and member access
- struct S2 NODEREF *s2_arr[10];
- struct S2 NODEREF *s2_arr2[10][10];
- p = s2_arr[1]->a;
- p = s2_arr[1]->b; // expected-warning{{dereferencing expression marked as 'noderef'}}
- int **bptr = &s2_arr[1]->b;
- x = s2->s2->a; // expected-warning{{dereferencing expression marked as 'noderef'}}
- x = s2_noderef->a[1]; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
- p = &s2_noderef->a[1];
- // Casting to dereferenceable pointer
- p2 = p; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
- p2 = *q; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
- p2 = q[0]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
- s2 = s2_arr[1]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
- s2 = s2_arr2[1][1]; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
- p2 = p, p2 = *q; // expected-warning 2 {{casting to dereferenceable pointer removes 'noderef' attribute}}
- // typedefs
- typedef int NODEREF *ptr_t;
- ptr_t ptr; // expected-note 2 {{ptr declared here}}
- ptr_t *ptr2;
- *ptr; // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}
- *ptr2;
- **ptr2; // expected-warning{{dereferencing expression marked as 'noderef'}}
- typedef struct S2 NODEREF *s2_ptr_t;
- s2_ptr_t s2_ptr; // expected-note 4 {{s2_ptr declared here}}
- s2_ptr->a; // ok since result is an array in a struct
- s2_ptr->a2; // ok
- s2_ptr->b; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
- s2_ptr->b2; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
- s2_ptr->s; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
- s2_ptr->s2; // expected-warning{{dereferencing s2_ptr; was declared with a 'noderef' type}}
- s2_ptr->a + 1;
- typedef int(int_t);
- typedef int_t NODEREF *(noderef_int_t);
- typedef noderef_int_t *noderef_int_nested_t;
- noderef_int_nested_t noderef_int_nested_ptr;
- *noderef_int_nested_ptr;
- **noderef_int_nested_ptr; // expected-warning{{dereferencing expression marked as 'noderef'}}
- typedef int_t *(NODEREF noderef_int2_t);
- typedef noderef_int2_t *noderef_int2_nested_t;
- noderef_int2_nested_t noderef_int2_nested_ptr; // expected-note{{noderef_int2_nested_ptr declared here}}
- *noderef_int2_nested_ptr; // expected-warning{{dereferencing noderef_int2_nested_ptr; was declared with a 'noderef' type}}
- typedef int_t *(noderef_int3_t);
- typedef noderef_int3_t(NODEREF(*(noderef_int3_nested_t)));
- noderef_int3_nested_t noderef_int3_nested_ptr; // expected-note{{noderef_int3_nested_ptr declared here}}
- *noderef_int3_nested_ptr; // expected-warning{{dereferencing noderef_int3_nested_ptr; was declared with a 'noderef' type}}
- // Parentheses
- (((*((p))))); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- (*(*(&(p)))); // expected-warning{{dereferencing expression marked as 'noderef'}}
- (p[1]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- (q[0]); // ok
- (q[0][0]); // expected-warning{{dereferencing expression marked as 'noderef'}}
- (q2[0]); // expected-warning{{dereferencing q2; was declared with a 'noderef' type}}
- (q[(*(p))]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- (p[(*(p))]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
- (*(ptr)); // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}
- (*(ptr2));
- (*(*(ptr2))); // expected-warning{{dereferencing expression marked as 'noderef'}}
- // Functions
- x = *(func(p)); // expected-warning{{dereferencing expression marked as 'noderef'}}
- // Casting is ok
- q = (int NODEREF **)&p;
- q = (int NODEREF **)&p2;
- q = &p;
- q = &p2;
- x = s2->s2->a; // expected-warning{{dereferencing expression marked as 'noderef'}}
- // Other expressions
- func2(*p); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- func2(*p + 1); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- func2(!*p); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- func2((x = *p)); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- func2((char)(*p)); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- // Other statements
- if (*p) {} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- else if (*p) {} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- switch (*p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- for (*p; *p; *p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
- // expected-warning@-2{{dereferencing p; was declared with a 'noderef' type}}
- for (*p; *p;){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
- for (*p;; *p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
- for (; *p; *p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- // expected-warning@-1{{dereferencing p; was declared with a 'noderef' type}}
- for (*p;;){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- for (;*p;){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- for (;;*p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- while (*p){} // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- do {} while (*p); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- return *p; // expected-warning{{dereferencing p; was declared with a 'noderef' type}}
- }
|