245 lines · c
1// RUN: %clang_cc1 -Wno-unused-value -verify %s2 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(void) {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 // Indirection37 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; // ok53 **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 access60 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}}63 p = &s->a;64 p = &(*s).b;65 66 // Most things in sizeof() can't actually access memory67 x = sizeof(s->a); // ok68 x = sizeof(*s); // ok69 x = sizeof(s[0]); // ok70 x = sizeof(s->a + (s->b)); // ok71 x = sizeof(int[++s->a]); // expected-warning{{dereferencing s; was declared with a 'noderef' type}}72 73 // Struct member access should carry NoDeref type information through to an74 // enclosing AddrOf.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'}}78 79 // Nested struct access80 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 struct82 p = (*s2_noderef).a; // ok since result is an array in a struct83 p = s2_noderef->a2; // ok84 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;89 90 struct S2 *s2;91 p = s2->a;92 p = s2->a2;93 p = s2->b;94 p = s2->b2;95 s = s2->s;96 s = s2->s2;97 &(*(*s2).s2).b;98 99 // Subscript access100 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}}106 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}}109 110 int NODEREF *(arr2[10]);111 int NODEREF *elem = *arr2;112 113 int NODEREF(*arr3)[10];114 elem = *arr3;115 116 // Combinations between indirection, subscript, and member access117 struct S2 NODEREF *s2_arr[10];118 struct S2 NODEREF *s2_arr2[10][10];119 120 p = s2_arr[1]->a;121 p = s2_arr[1]->b; // expected-warning{{dereferencing expression marked as 'noderef'}}122 int *NODEREF *bptr = &s2_arr[1]->b;123 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];127 128 // Casting to dereferenceable pointer129 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}}135 136 // typedefs137 typedef int NODEREF *ptr_t;138 ptr_t ptr; // expected-note 2 {{ptr declared here}}139 ptr_t *ptr2;140 *ptr; // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}141 *ptr2;142 **ptr2; // expected-warning{{dereferencing expression marked as 'noderef'}}143 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 struct147 s2_ptr->a2; // ok148 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}}152 s2_ptr->a + 1;153 154 typedef int(int_t);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'}}160 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}}165 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}}170 171 // Parentheses172 (((*((p))))); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}173 (*(*(&(p)))); // expected-warning{{dereferencing expression marked as 'noderef'}}174 175 (p[1]); // expected-warning{{dereferencing p; was declared with a 'noderef' type}}176 (q[0]); // ok177 (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}}182 183 (*(ptr)); // expected-warning{{dereferencing ptr; was declared with a 'noderef' type}}184 (*(ptr2));185 (*(*(ptr2))); // expected-warning{{dereferencing expression marked as 'noderef'}}186 187 // Functions188 x = *(func(p)); // expected-warning{{dereferencing expression marked as 'noderef'}}189 190 // Casting is ok191 q = (int NODEREF **)&p;192 q = (int NODEREF **)&p2;193 q = &p;194 q = &p2;195 x = s2->s2->a; // expected-warning{{dereferencing expression marked as 'noderef'}}196 197 // Other expressions198 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}}203 204 // Other statements205 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}}223}224 225// FIXME: Currently, [[]] syntax does not work for the `noderef` atribute.226// For the time being, test that we consistently diagnose the attribute as227// ignored.228// For details see https://github.com/llvm/llvm-project/issues/55790229void test_standard_syntax() {230 [[clang::noderef]] int i; // expected-warning {{'clang::noderef' attribute ignored}}231 232 [[clang::noderef]] int *p1; // expected-warning {{'clang::noderef' attribute ignored}}233 *p1;234 235 int *p2 [[clang::noderef]]; // expected-warning {{'clang::noderef' attribute ignored}}236 *p2;237 238 int * [[clang::noderef]] p3; // expected-warning {{'clang::noderef' attribute ignored}}239 *p3;240 241 typedef int* IntPtr;242 [[clang::noderef]] IntPtr p4; // expected-warning {{'clang::noderef' attribute ignored}}243 *p4;244}245