summaryrefslogtreecommitdiff
path: root/clang/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p5.cpp
blob: c02105ca76cfa0deb6e5570e2a8c6572fc076a14 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// RUN: %clang_cc1 -fsyntax-only -verify %s

// C++ [dcl.ref]p5:
//   There shall be no references to references, no arrays of
//   references, and no pointers to references.

// The crazy formatting in here is to enforce the exact report locations.

typedef int &intref;
typedef intref &intrefref;

template <class T> class RefMem { // expected-warning{{class 'RefMem<int &>' does not declare any constructor to initialize its non-modifiable members}}
  T
    &
      member; // expected-note{{reference member 'member' will never be initialized}}
};

struct RefRef {
  int
      &
        &             // expected-error {{declared as a reference to a reference}}
          refref0;

  intref
         &
           refref1; // collapses

  intrefref
            &
              refref2; // collapses

  RefMem
        <
         int
            &
             >
               refref3; // collapses expected-note{{in instantiation of template class 'RefMem<int &>' requested here}}
};


template <class T> class PtrMem {
  T
    *                   // expected-error {{declared as a pointer to a reference}}
      member;
};

struct RefPtr {
  typedef
          int
              &
                *       // expected-error {{declared as a pointer to a reference}}
                  intrefptr;

  typedef
          intref
                 *      // expected-error {{declared as a pointer to a reference}}
                   intrefptr2;

  int
      &
        *               // expected-error {{declared as a pointer to a reference}}
          refptr0;

  intref
         *              // expected-error {{declared as a pointer to a reference}}
           refptr1;

  PtrMem
        <
         int
            &
             >
               refptr2; // expected-note {{in instantiation}}
};

template <class T> class ArrMem {
  T
    member
           [ // expected-error {{declared as array of references}}
            10
              ];
};
template <class T, unsigned N> class DepArrMem {
  T
    member
           [ // expected-error {{declared as array of references}}
            N
             ];
};

struct RefArr {
  typedef 
          int
              &
                intrefarr
                         [ // expected-error {{declared as array of references}}
                          2
                           ];

  typedef
          intref
                 intrefarr
                          [ // expected-error {{declared as array of references}}
                           2
                            ];

  int
      &
        refarr0
               [ // expected-error {{declared as array of references}}
                2
                 ];
  intref
         refarr1
                [ // expected-error {{declared as array of references}}
                 2
                  ];
  ArrMem
        <
         int
            &
             >
               refarr2; // expected-note {{in instantiation}}
  DepArrMem
           <
            int
               &,
                  10
                    >
                      refarr3; // expected-note {{in instantiation}}
};


//   The declaration of a reference shall contain an initializer
//   (8.5.3) except when the declaration contains an explicit extern
//   specifier (7.1.1), is a class member (9.2) declaration within a
//   class definition, or is the declaration of a parameter or a
//   return type (8.3.5); see 3.1. A reference shall be initialized to
//   refer to a valid object or function. [ Note: in particular, a
//   null reference cannot exist in a well-defined program, because
//   the only way to create such a reference would be to bind it to
//   the "object" obtained by dereferencing a null pointer, which
//   causes undefined behavior. As described in 9.6, a reference
//   cannot be bound directly to a bit-field.