1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
2 | |
3 | // C++ [dcl.ref]p5: |
4 | // There shall be no references to references, no arrays of |
5 | // references, and no pointers to references. |
6 | |
7 | // The crazy formatting in here is to enforce the exact report locations. |
8 | |
9 | typedef int &intref; |
10 | typedef intref &intrefref; |
11 | |
12 | template <class T> class RefMem { // expected-warning{{class 'RefMem<int &>' does not declare any constructor to initialize its non-modifiable members}} |
13 | T |
14 | & |
15 | member; // expected-note{{reference member 'member' will never be initialized}} |
16 | }; |
17 | |
18 | struct RefRef { |
19 | int |
20 | & |
21 | & // expected-error {{declared as a reference to a reference}} |
22 | refref0; |
23 | |
24 | intref |
25 | & |
26 | refref1; // collapses |
27 | |
28 | intrefref |
29 | & |
30 | refref2; // collapses |
31 | |
32 | RefMem |
33 | < |
34 | int |
35 | & |
36 | > |
37 | refref3; // collapses expected-note{{in instantiation of template class 'RefMem<int &>' requested here}} |
38 | }; |
39 | |
40 | |
41 | template <class T> class PtrMem { |
42 | T |
43 | * // expected-error {{declared as a pointer to a reference}} |
44 | member; |
45 | }; |
46 | |
47 | struct RefPtr { |
48 | typedef |
49 | int |
50 | & |
51 | * // expected-error {{declared as a pointer to a reference}} |
52 | intrefptr; |
53 | |
54 | typedef |
55 | intref |
56 | * // expected-error {{declared as a pointer to a reference}} |
57 | intrefptr2; |
58 | |
59 | int |
60 | & |
61 | * // expected-error {{declared as a pointer to a reference}} |
62 | refptr0; |
63 | |
64 | intref |
65 | * // expected-error {{declared as a pointer to a reference}} |
66 | refptr1; |
67 | |
68 | PtrMem |
69 | < |
70 | int |
71 | & |
72 | > |
73 | refptr2; // expected-note {{in instantiation}} |
74 | }; |
75 | |
76 | template <class T> class ArrMem { |
77 | T |
78 | member |
79 | [ // expected-error {{declared as array of references}} |
80 | 10 |
81 | ]; |
82 | }; |
83 | template <class T, unsigned N> class DepArrMem { |
84 | T |
85 | member |
86 | [ // expected-error {{declared as array of references}} |
87 | N |
88 | ]; |
89 | }; |
90 | |
91 | struct RefArr { |
92 | typedef |
93 | int |
94 | & |
95 | intrefarr |
96 | [ // expected-error {{declared as array of references}} |
97 | 2 |
98 | ]; |
99 | |
100 | typedef |
101 | intref |
102 | intrefarr |
103 | [ // expected-error {{declared as array of references}} |
104 | 2 |
105 | ]; |
106 | |
107 | int |
108 | & |
109 | refarr0 |
110 | [ // expected-error {{declared as array of references}} |
111 | 2 |
112 | ]; |
113 | intref |
114 | refarr1 |
115 | [ // expected-error {{declared as array of references}} |
116 | 2 |
117 | ]; |
118 | ArrMem |
119 | < |
120 | int |
121 | & |
122 | > |
123 | refarr2; // expected-note {{in instantiation}} |
124 | DepArrMem |
125 | < |
126 | int |
127 | &, |
128 | 10 |
129 | > |
130 | refarr3; // expected-note {{in instantiation}} |
131 | }; |
132 | |
133 | |
134 | // The declaration of a reference shall contain an initializer |
135 | // (8.5.3) except when the declaration contains an explicit extern |
136 | // specifier (7.1.1), is a class member (9.2) declaration within a |
137 | // class definition, or is the declaration of a parameter or a |
138 | // return type (8.3.5); see 3.1. A reference shall be initialized to |
139 | // refer to a valid object or function. [ Note: in particular, a |
140 | // null reference cannot exist in a well-defined program, because |
141 | // the only way to create such a reference would be to bind it to |
142 | // the "object" obtained by dereferencing a null pointer, which |
143 | // causes undefined behavior. As described in 9.6, a reference |
144 | // cannot be bound directly to a bit-field. |
145 | |
146 | |