1 // RUN: %clang_cc1 -fblocks -verify %s 2 3 /** 4 * Test 'noderef' attribute with c++ constructs. 5 */ 6 7 #define NODEREF __attribute__((noderef)) 8 9 void Normal() { 10 int NODEREF i; // expected-warning{{'noderef' can only be used on an array or pointer type}} 11 int NODEREF *i_ptr; // expected-note 2 {{i_ptr declared here}} 12 int NODEREF **i_ptr2; // ok 13 int *NODEREF i_ptr3; // expected-warning{{'noderef' can only be used on an array or pointer type}} 14 int *NODEREF *i_ptr4; // ok 15 16 auto NODEREF *auto_i_ptr = i_ptr; 17 auto NODEREF auto_i = i; // expected-warning{{'noderef' can only be used on an array or pointer type}} 18 19 struct { 20 int x; 21 int y; 22 } NODEREF *s; 23 24 int __attribute__((noderef(10))) * no_args; // expected-error{{'noderef' attribute takes no arguments}} 25 26 int i2 = *i_ptr; // expected-warning{{dereferencing i_ptr; was declared with a 'noderef' type}} 27 int &i3 = *i_ptr; // expected-warning{{dereferencing i_ptr; was declared with a 'noderef' type}} 28 int *i_ptr5 = i_ptr; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}} 29 int *i_ptr6(i_ptr); // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}} 30 } 31 32 const int NODEREF *const_i_ptr; 33 static int NODEREF *static_i_ptr; 34 35 void ParenTypes() { 36 int NODEREF(*i_ptr); // ok (same as `int NODEREF *`) 37 int NODEREF *(*i_ptr2); // ok (same as `int NODEREF **`) 38 } 39 40 // Function declarations 41 int NODEREF func(); // expected-warning{{'noderef' can only be used on an array or pointer type}} 42 int NODEREF *func2(); // ok (returning pointer) 43 44 typedef int NODEREF (*func3)(int); // expected-warning{{'noderef' can only be used on an array or pointer type}} 45 typedef int NODEREF *(*func4)(int); 46 47 void Arrays() { 48 int NODEREF i_arr[10]; // ok 49 int NODEREF i_arr2[10][10]; // ok 50 int NODEREF *i_arr3[10]; // ok 51 int NODEREF i_arr4[] = {1, 2}; 52 } 53 54 void ParenArrays() { 55 int NODEREF(i_ptr[10]); 56 int NODEREF(i_ptr2[10])[10]; 57 } 58 59 typedef int NODEREF *(*func5[10])(int); 60 61 // Arguments 62 void func6(int NODEREF x); // expected-warning{{'noderef' can only be used on an array or pointer type}} 63 void func7(int NODEREF *x); 64 void func8() NODEREF; 65 66 void References() { 67 int x = 2; 68 int NODEREF &y = x; // expected-warning{{'noderef' can only be used on an array or pointer type}} 69 int *xp = &x; 70 int NODEREF *&a = xp; // ok (reference to a NODEREF *) 71 int *NODEREF &b = xp; // expected-warning{{'noderef' can only be used on an array or pointer type}} 72 } 73 74 void BlockPointers() { 75 typedef int NODEREF (^IntBlock)(); // expected-warning{{'noderef' can only be used on an array or pointer type}} 76 } 77 78 class A { 79 public: 80 int member; 81 int NODEREF *member2; 82 int NODEREF member3; // expected-warning{{'noderef' can only be used on an array or pointer type}} 83 }; 84 85 void MemberPointer() { 86 int NODEREF A::*var = &A::member; // expected-warning{{'noderef' can only be used on an array or pointer type}} 87 } 88 89 template <class Ty> 90 class B { 91 Ty NODEREF *member; 92 Ty NODEREF member2; // expected-warning{{'noderef' can only be used on an array or pointer type}} 93 }; 94 95 void test_lambdas() { 96 auto l = [](int NODEREF *x){ // expected-note{{x declared here}} 97 return *x; // expected-warning{{dereferencing x; was declared with a 'noderef' type}} 98 }; 99 } 100 101 int NODEREF *glob_ptr; // expected-note{{glob_ptr declared here}} 102 int glob_int = *glob_ptr; // expected-warning{{dereferencing glob_ptr; was declared with a 'noderef' type}} 103