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 | |