xref: /llvm-project/clang/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p5.cpp (revision 553b2b2e5dde2839618edbc7b60f6c0677774853)
18fbe78f6SDaniel Dunbar // RUN: %clang_cc1 -fsyntax-only -verify %s
270dd5f65SJohn McCall 
370dd5f65SJohn McCall // C++ [dcl.ref]p5:
470dd5f65SJohn McCall //   There shall be no references to references, no arrays of
570dd5f65SJohn McCall //   references, and no pointers to references.
670dd5f65SJohn McCall 
770dd5f65SJohn McCall // The crazy formatting in here is to enforce the exact report locations.
870dd5f65SJohn McCall 
970dd5f65SJohn McCall typedef int &intref;
1070dd5f65SJohn McCall typedef intref &intrefref;
1170dd5f65SJohn McCall 
12*454a5b65SDouglas Gregor template <class T> class RefMem { // expected-warning{{class 'RefMem<int &>' does not declare any constructor to initialize its non-modifiable members}}
1370dd5f65SJohn McCall   T
1470dd5f65SJohn McCall     &
15*454a5b65SDouglas Gregor       member; // expected-note{{reference member 'member' will never be initialized}}
1670dd5f65SJohn McCall };
1770dd5f65SJohn McCall 
1870dd5f65SJohn McCall struct RefRef {
1970dd5f65SJohn McCall   int
2070dd5f65SJohn McCall       &
2170dd5f65SJohn McCall         &             // expected-error {{declared as a reference to a reference}}
2270dd5f65SJohn McCall           refref0;
2370dd5f65SJohn McCall 
2470dd5f65SJohn McCall   intref
2570dd5f65SJohn McCall          &
2670dd5f65SJohn McCall            refref1; // collapses
2770dd5f65SJohn McCall 
2870dd5f65SJohn McCall   intrefref
2970dd5f65SJohn McCall             &
3070dd5f65SJohn McCall               refref2; // collapses
3170dd5f65SJohn McCall 
3270dd5f65SJohn McCall   RefMem
3370dd5f65SJohn McCall         <
3470dd5f65SJohn McCall          int
3570dd5f65SJohn McCall             &
3670dd5f65SJohn McCall              >
37*454a5b65SDouglas Gregor                refref3; // collapses expected-note{{in instantiation of template class 'RefMem<int &>' requested here}}
3870dd5f65SJohn McCall };
3970dd5f65SJohn McCall 
4070dd5f65SJohn McCall 
4170dd5f65SJohn McCall template <class T> class PtrMem {
4270dd5f65SJohn McCall   T
4370dd5f65SJohn McCall     *                   // expected-error {{declared as a pointer to a reference}}
4470dd5f65SJohn McCall       member;
4570dd5f65SJohn McCall };
4670dd5f65SJohn McCall 
4770dd5f65SJohn McCall struct RefPtr {
4870dd5f65SJohn McCall   typedef
4970dd5f65SJohn McCall           int
5070dd5f65SJohn McCall               &
5170dd5f65SJohn McCall                 *       // expected-error {{declared as a pointer to a reference}}
5270dd5f65SJohn McCall                   intrefptr;
5370dd5f65SJohn McCall 
5470dd5f65SJohn McCall   typedef
5570dd5f65SJohn McCall           intref
5670dd5f65SJohn McCall                  *      // expected-error {{declared as a pointer to a reference}}
5770dd5f65SJohn McCall                    intrefptr2;
5870dd5f65SJohn McCall 
5970dd5f65SJohn McCall   int
6070dd5f65SJohn McCall       &
6170dd5f65SJohn McCall         *               // expected-error {{declared as a pointer to a reference}}
6270dd5f65SJohn McCall           refptr0;
6370dd5f65SJohn McCall 
6470dd5f65SJohn McCall   intref
6570dd5f65SJohn McCall          *              // expected-error {{declared as a pointer to a reference}}
6670dd5f65SJohn McCall            refptr1;
6770dd5f65SJohn McCall 
6870dd5f65SJohn McCall   PtrMem
6970dd5f65SJohn McCall         <
7070dd5f65SJohn McCall          int
7170dd5f65SJohn McCall             &
7270dd5f65SJohn McCall              >
7370dd5f65SJohn McCall                refptr2; // expected-note {{in instantiation}}
7470dd5f65SJohn McCall };
7570dd5f65SJohn McCall 
7670dd5f65SJohn McCall template <class T> class ArrMem {
7770dd5f65SJohn McCall   T
7870dd5f65SJohn McCall     member
7970dd5f65SJohn McCall            [ // expected-error {{declared as array of references}}
8070dd5f65SJohn McCall             10
8170dd5f65SJohn McCall               ];
8270dd5f65SJohn McCall };
8370dd5f65SJohn McCall template <class T, unsigned N> class DepArrMem {
8470dd5f65SJohn McCall   T
8570dd5f65SJohn McCall     member
8670dd5f65SJohn McCall            [ // expected-error {{declared as array of references}}
8770dd5f65SJohn McCall             N
8870dd5f65SJohn McCall              ];
8970dd5f65SJohn McCall };
9070dd5f65SJohn McCall 
9170dd5f65SJohn McCall struct RefArr {
9270dd5f65SJohn McCall   typedef
9370dd5f65SJohn McCall           int
9470dd5f65SJohn McCall               &
9570dd5f65SJohn McCall                 intrefarr
9670dd5f65SJohn McCall                          [ // expected-error {{declared as array of references}}
9770dd5f65SJohn McCall                           2
9870dd5f65SJohn McCall                            ];
9970dd5f65SJohn McCall 
10070dd5f65SJohn McCall   typedef
10170dd5f65SJohn McCall           intref
10270dd5f65SJohn McCall                  intrefarr
10370dd5f65SJohn McCall                           [ // expected-error {{declared as array of references}}
10470dd5f65SJohn McCall                            2
10570dd5f65SJohn McCall                             ];
10670dd5f65SJohn McCall 
10770dd5f65SJohn McCall   int
10870dd5f65SJohn McCall       &
10970dd5f65SJohn McCall         refarr0
11070dd5f65SJohn McCall                [ // expected-error {{declared as array of references}}
11170dd5f65SJohn McCall                 2
11270dd5f65SJohn McCall                  ];
11370dd5f65SJohn McCall   intref
11470dd5f65SJohn McCall          refarr1
11570dd5f65SJohn McCall                 [ // expected-error {{declared as array of references}}
11670dd5f65SJohn McCall                  2
11770dd5f65SJohn McCall                   ];
11870dd5f65SJohn McCall   ArrMem
11970dd5f65SJohn McCall         <
12070dd5f65SJohn McCall          int
12170dd5f65SJohn McCall             &
12270dd5f65SJohn McCall              >
12370dd5f65SJohn McCall                refarr2; // expected-note {{in instantiation}}
12470dd5f65SJohn McCall   DepArrMem
12570dd5f65SJohn McCall            <
12670dd5f65SJohn McCall             int
12770dd5f65SJohn McCall                &,
12870dd5f65SJohn McCall                   10
12970dd5f65SJohn McCall                     >
13070dd5f65SJohn McCall                       refarr3; // expected-note {{in instantiation}}
13170dd5f65SJohn McCall };
13270dd5f65SJohn McCall 
13370dd5f65SJohn McCall 
13470dd5f65SJohn McCall //   The declaration of a reference shall contain an initializer
13570dd5f65SJohn McCall //   (8.5.3) except when the declaration contains an explicit extern
13670dd5f65SJohn McCall //   specifier (7.1.1), is a class member (9.2) declaration within a
13770dd5f65SJohn McCall //   class definition, or is the declaration of a parameter or a
13870dd5f65SJohn McCall //   return type (8.3.5); see 3.1. A reference shall be initialized to
13970dd5f65SJohn McCall //   refer to a valid object or function. [ Note: in particular, a
14070dd5f65SJohn McCall //   null reference cannot exist in a well-defined program, because
14170dd5f65SJohn McCall //   the only way to create such a reference would be to bind it to
14270dd5f65SJohn McCall //   the "object" obtained by dereferencing a null pointer, which
14370dd5f65SJohn McCall //   causes undefined behavior. As described in 9.6, a reference
14470dd5f65SJohn McCall //   cannot be bound directly to a bit-field.
14570dd5f65SJohn McCall 
146