diff options
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/Frontend/noderef.c | 209 | ||||
-rw-r--r-- | clang/test/Frontend/noderef.cpp | 102 | ||||
-rw-r--r-- | clang/test/Frontend/noderef_on_non_pointers.m | 11 | ||||
-rw-r--r-- | clang/test/Frontend/noderef_templates.cpp | 15 |
4 files changed, 337 insertions, 0 deletions
diff --git a/clang/test/Frontend/noderef.c b/clang/test/Frontend/noderef.c new file mode 100644 index 00000000000..b072b995fcf --- /dev/null +++ b/clang/test/Frontend/noderef.c @@ -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}} +} diff --git a/clang/test/Frontend/noderef.cpp b/clang/test/Frontend/noderef.cpp new file mode 100644 index 00000000000..15eb4e457c2 --- /dev/null +++ b/clang/test/Frontend/noderef.cpp @@ -0,0 +1,102 @@ +// RUN: %clang_cc1 -fblocks -verify %s + +/** + * Test 'noderef' attribute with c++ constructs. + */ + +#define NODEREF __attribute__((noderef)) + +void Normal() { + int NODEREF i; // expected-warning{{'noderef' can only be used on an array or pointer type}} + int NODEREF *i_ptr; // expected-note 2 {{i_ptr declared here}} + int NODEREF **i_ptr2; // ok + int *NODEREF i_ptr3; // expected-warning{{'noderef' can only be used on an array or pointer type}} + int *NODEREF *i_ptr4; // ok + + auto NODEREF *auto_i_ptr = i_ptr; + auto NODEREF auto_i = i; // expected-warning{{'noderef' can only be used on an array or pointer type}} + + struct { + int x; + int y; + } NODEREF *s; + + int __attribute__((noderef(10))) * no_args; // expected-error{{'noderef' attribute takes no arguments}} + + int i2 = *i_ptr; // expected-warning{{dereferencing i_ptr; was declared with a 'noderef' type}} + int &i3 = *i_ptr; // expected-warning{{dereferencing i_ptr; was declared with a 'noderef' type}} + int *i_ptr5 = i_ptr; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}} + int *i_ptr6(i_ptr); // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}} +} + +const int NODEREF *const_i_ptr; +static int NODEREF *static_i_ptr; + +void ParenTypes() { + int NODEREF(*i_ptr); // ok (same as `int NODEREF *`) + int NODEREF *(*i_ptr2); // ok (same as `int NODEREF **`) +} + +// Function declarations +int NODEREF func(); // expected-warning{{'noderef' can only be used on an array or pointer type}} +int NODEREF *func2(); // ok (returning pointer) + +typedef int NODEREF (*func3)(int); // expected-warning{{'noderef' can only be used on an array or pointer type}} +typedef int NODEREF *(*func4)(int); + +void Arrays() { + int NODEREF i_arr[10]; // ok + int NODEREF i_arr2[10][10]; // ok + int NODEREF *i_arr3[10]; // ok + int NODEREF i_arr4[] = {1, 2}; +} + +void ParenArrays() { + int NODEREF(i_ptr[10]); + int NODEREF(i_ptr2[10])[10]; +} + +typedef int NODEREF *(*func5[10])(int); + +// Arguments +void func6(int NODEREF x); // expected-warning{{'noderef' can only be used on an array or pointer type}} +void func7(int NODEREF *x); +void func8() NODEREF; + +void References() { + int x = 2; + int NODEREF &y = x; // expected-warning{{'noderef' can only be used on an array or pointer type}} + int *xp = &x; + int NODEREF *&a = xp; // ok (reference to a NODEREF *) + int *NODEREF &b = xp; // expected-warning{{'noderef' can only be used on an array or pointer type}} +} + +void BlockPointers() { + typedef int NODEREF (^IntBlock)(); // expected-warning{{'noderef' can only be used on an array or pointer type}} +} + +class A { +public: + int member; + int NODEREF *member2; + int NODEREF member3; // expected-warning{{'noderef' can only be used on an array or pointer type}} +}; + +void MemberPointer() { + int NODEREF A::*var = &A::member; // expected-warning{{'noderef' can only be used on an array or pointer type}} +} + +template <class Ty> +class B { + Ty NODEREF *member; + Ty NODEREF member2; // expected-warning{{'noderef' can only be used on an array or pointer type}} +}; + +void test_lambdas() { + auto l = [](int NODEREF *x){ // expected-note{{x declared here}} + return *x; // expected-warning{{dereferencing x; was declared with a 'noderef' type}} + }; +} + +int NODEREF *glob_ptr; // expected-note{{glob_ptr declared here}} +int glob_int = *glob_ptr; // expected-warning{{dereferencing glob_ptr; was declared with a 'noderef' type}} diff --git a/clang/test/Frontend/noderef_on_non_pointers.m b/clang/test/Frontend/noderef_on_non_pointers.m new file mode 100644 index 00000000000..ced7627bb5e --- /dev/null +++ b/clang/test/Frontend/noderef_on_non_pointers.m @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -verify %s + +#define NODEREF __attribute__((noderef)) + +@interface NSObject ++ (id)new; +@end + +void func() { + id NODEREF obj = [NSObject new]; // expected-warning{{'noderef' can only be used on an array or pointer type}} +} diff --git a/clang/test/Frontend/noderef_templates.cpp b/clang/test/Frontend/noderef_templates.cpp new file mode 100644 index 00000000000..5fde6efd87c --- /dev/null +++ b/clang/test/Frontend/noderef_templates.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -verify %s + +#define NODEREF __attribute__((noderef)) + +template <typename T> +int func(T NODEREF *a) { // expected-note 2 {{a declared here}} + return *a + 1; // expected-warning 2 {{dereferencing a; was declared with a 'noderef' type}} +} + +void func() { + float NODEREF *f; + int NODEREF *i; + func(f); // expected-note{{in instantiation of function template specialization 'func<float>' requested here}} + func(i); // expected-note{{in instantiation of function template specialization 'func<int>' requested here}} +} |