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