|
@@ -0,0 +1,209 @@
|
|
|
+// 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}}
|
|
|
+}
|