xref: /llvm-project/clang/test/SemaCXX/cxx0x-initializer-references.cpp (revision ae73706075bb2ea4bbc87c4b33f3b681555f8dfb)
1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -fexperimental-new-constant-interpreter
3 
4 struct one { char c; };
5 struct two { char c[2]; };
6 
7 namespace reference {
8   struct A {
9     int i1, i2;
10   };
11 
single_init()12   void single_init() {
13     const int &cri1a = {1};
14     const int &cri1b{1};
15 
16     int i = 1;
17     int &ri1a = {i};
18     int &ri1b{i};
19 
20     int &ri2 = {1}; // expected-error {{cannot bind to an initializer list temporary}}
21 
22     A a{1, 2};
23     A &ra1a = {a};
24     A &ra1b{a};
25   }
26 
reference_to_aggregate()27   void reference_to_aggregate() {
28     const A &ra1{1, 2};
29     A &ra2{1, 2}; // expected-error {{cannot bind to an initializer list temporary}}
30 
31     const int (&arrayRef)[] = {1, 2, 3};
32     static_assert(sizeof(arrayRef) == 3 * sizeof(int), "bad array size");
33   }
34 
35   struct B {
36     int i1;
37   };
38 
call()39   void call() {
40     one f(const int&);
41     f({1});
42 
43     one g(int&); // expected-note {{passing argument}}
44     g({1}); // expected-error {{cannot bind to an initializer list temporary}}
45     int i = 0;
46     g({i});
47 
48     void h(const B&);
49     h({1});
50 
51     void a(B&); // expected-note {{passing argument}}
52     a({1}); // expected-error {{cannot bind to an initializer list temporary}}
53     B b{1};
54     a({b});
55   }
56 
overloading()57   void overloading() {
58     one f(const int&);
59     two f(const B&);
60 
61     // First is identity conversion, second is user-defined conversion.
62     static_assert(sizeof(f({1})) == sizeof(one), "bad overload resolution");
63 
64     one g(int&);
65     two g(const B&);
66 
67     static_assert(sizeof(g({1})) == sizeof(two), "bad overload resolution");
68 
69     one h(const int&);
70     two h(const A&);
71 
72     static_assert(sizeof(h({1, 2})) == sizeof(two), "bad overload resolution");
73   }
74 
75   struct X {};
76 
edge_cases()77   void edge_cases() {
78     int const &b({0}); // expected-error {{cannot initialize reference type 'const int &' with a parenthesized initializer list}}
79     const int (&arr)[3] ({1, 2, 3}); // expected-error {{cannot initialize reference type 'const int (&)[3]' with a parenthesized initializer list}}
80     const X &x({}); // expected-error {{cannot initialize reference type 'const X &' with a parenthesized initializer list}}
81   }
82 
dependent_edge_cases()83   template<typename T> void dependent_edge_cases() {
84     T b({}); // expected-error-re 3{{cannot initialize reference type {{.*}} with a parenthesized init}}
85     T({}); // expected-error-re 3{{cannot initialize reference type {{.*}} with a parenthesized init}}
86   }
87   template void dependent_edge_cases<X>(); // ok
88   template void dependent_edge_cases<const int&>(); // expected-note {{instantiation of}}
89   template void dependent_edge_cases<const int(&)[1]>(); // expected-note {{instantiation of}}
90   template void dependent_edge_cases<const X&>(); // expected-note {{instantiation of}}
91 }
92 
93 namespace PR12182 {
94   void f(int const(&)[3]);
95 
g()96   void g() {
97       f({1, 2});
98   }
99 }
100 
101 namespace PR12660 {
102   const int &i { 1 };
103   struct S { S(int); } const &s { 2 };
104 }
105 
106 namespace b7891773 {
107   typedef void (*ptr)();
108   template <class T> void f();
109   int g(const ptr &);
110   int k = g({ f<int> });
111 }
112 
113 namespace inner_init {
114   struct A { int n; };
115   struct B { A &&r; };
116   B b1 { 0 }; // expected-error {{reference to type 'A' could not bind to an rvalue of type 'int'}}
117   B b2 { { 0 } };
118   B b3 { { { 0 } } }; // expected-warning {{braces around scalar init}}
119 
120   struct C { C(int); };   // expected-note 2{{candidate constructor (the implicit}} \
121                           // expected-note {{candidate constructor not viable: cannot convert initializer list argument to 'int'}}
122   struct D { C &&r; };
123   D d1 { 0 }; // ok, 0 implicitly converts to C
124   D d2 { { 0 } }; // ok, { 0 } calls C(0)
125   D d3 { { { 0 } } }; // ok, { { 0 } } calls C({ 0 }), expected-warning {{braces around scalar init}}
126   D d4 { { { { 0 } } } }; // expected-error {{no matching constructor for initialization of 'C &&'}}
127 
128   struct E { explicit E(int); }; // expected-note 2{{here}}
129   struct F { E &&r; };
130   F f1 { 0 }; // expected-error {{could not bind to an rvalue of type 'int'}}
131   F f2 { { 0 } }; // expected-error {{chosen constructor is explicit}}
132   F f3 { { { 0 } } }; // expected-error {{chosen constructor is explicit}}
133 }
134 
135 namespace PR20844 {
136   struct A {};
137   struct B { operator A&(); } b;
138   A &a{b}; // expected-error {{excess elements}} expected-note {{in initialization of temporary of type 'A'}}
139 }
140 
141 namespace PR21834 {
142 const int &a = (const int &){0}; // expected-error {{cannot bind to an initializer list}}
143 }
144 
145 namespace GH59100 {
146 class v {};
147 
148 template <typename T>
149 class V : public v {};
150 
151 using T = const V<int> &;
152 
153 template <class D>
f()154 void f() {
155   auto t = T{};
156 }
157 
z()158 void z()  {
159     f<int>();
160 }
161 }
162