2012-01-18 06:49:42 +08:00
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2012-01-24 06:09:39 +08:00
// This must obviously come before the definition of std::initializer_list.
void missing_initializerlist ( ) {
auto l = { 1 , 2 , 3 , 4 } ; // expected-error {{std::initializer_list was not found}}
}
2012-01-18 06:49:42 +08:00
namespace std {
typedef decltype ( sizeof ( int ) ) size_t ;
// libc++'s implementation
template < class _E >
class initializer_list
{
const _E * __begin_ ;
size_t __size_ ;
initializer_list ( const _E * __b , size_t __s )
: __begin_ ( __b ) ,
__size_ ( __s )
{ }
public :
typedef _E value_type ;
typedef const _E & reference ;
typedef const _E & const_reference ;
typedef size_t size_type ;
typedef const _E * iterator ;
typedef const _E * const_iterator ;
initializer_list ( ) : __begin_ ( nullptr ) , __size_ ( 0 ) { }
size_t size ( ) const { return __size_ ; }
const _E * begin ( ) const { return __begin_ ; }
const _E * end ( ) const { return __begin_ + __size_ ; }
} ;
}
2012-01-18 06:49:58 +08:00
template < typename T , typename U >
struct same_type { static const bool value = false ; } ;
template < typename T >
struct same_type < T , T > { static const bool value = true ; } ;
2012-01-18 06:49:42 +08:00
struct one { char c [ 1 ] ; } ;
struct two { char c [ 2 ] ; } ;
struct A {
int a , b ;
} ;
struct B {
B ( ) ;
B ( int , int ) ;
} ;
void simple_list ( ) {
std : : initializer_list < int > il = { 1 , 2 , 3 } ;
std : : initializer_list < double > dl = { 1.0 , 2.0 , 3 } ;
std : : initializer_list < A > al = { { 1 , 2 } , { 2 , 3 } , { 3 , 4 } } ;
std : : initializer_list < B > bl = { { 1 , 2 } , { 2 , 3 } , { } } ;
}
void function_call ( ) {
void f ( std : : initializer_list < int > ) ;
f ( { 1 , 2 , 3 } ) ;
void g ( std : : initializer_list < B > ) ;
g ( { { 1 , 2 } , { 2 , 3 } , { } } ) ;
}
2012-01-18 06:49:48 +08:00
struct C {
C ( int ) ;
} ;
struct D {
D ( ) ;
operator int ( ) ;
operator C ( ) ;
} ;
void overloaded_call ( ) {
one overloaded ( std : : initializer_list < int > ) ;
two overloaded ( std : : initializer_list < B > ) ;
static_assert ( sizeof ( overloaded ( { 1 , 2 , 3 } ) ) = = sizeof ( one ) , " bad overload " ) ;
static_assert ( sizeof ( overloaded ( { { 1 , 2 } , { 2 , 3 } , { } } ) ) = = sizeof ( two ) , " bad overload " ) ;
void ambiguous ( std : : initializer_list < A > ) ; // expected-note {{candidate}}
void ambiguous ( std : : initializer_list < B > ) ; // expected-note {{candidate}}
ambiguous ( { { 1 , 2 } , { 2 , 3 } , { 3 , 4 } } ) ; // expected-error {{ambiguous}}
one ov2 ( std : : initializer_list < int > ) ; // expected-note {{candidate}}
two ov2 ( std : : initializer_list < C > ) ; // expected-note {{candidate}}
// Worst sequence to int is identity, whereas to C it's user-defined.
static_assert ( sizeof ( ov2 ( { 1 , 2 , 3 } ) ) = = sizeof ( one ) , " bad overload " ) ;
// But here, user-defined is worst in both cases.
ov2 ( { 1 , 2 , D ( ) } ) ; // expected-error {{ambiguous}}
}
2012-01-18 06:49:58 +08:00
template < typename T >
T deduce ( std : : initializer_list < T > ) ; // expected-note {{conflicting types for parameter 'T' ('int' vs. 'double')}}
template < typename T >
T deduce_ref ( const std : : initializer_list < T > & ) ; // expected-note {{conflicting types for parameter 'T' ('int' vs. 'double')}}
void argument_deduction ( ) {
static_assert ( same_type < decltype ( deduce ( { 1 , 2 , 3 } ) ) , int > : : value , " bad deduction " ) ;
static_assert ( same_type < decltype ( deduce ( { 1.0 , 2.0 , 3.0 } ) ) , double > : : value , " bad deduction " ) ;
deduce ( { 1 , 2.0 } ) ; // expected-error {{no matching function}}
static_assert ( same_type < decltype ( deduce_ref ( { 1 , 2 , 3 } ) ) , int > : : value , " bad deduction " ) ;
static_assert ( same_type < decltype ( deduce_ref ( { 1.0 , 2.0 , 3.0 } ) ) , double > : : value , " bad deduction " ) ;
deduce_ref ( { 1 , 2.0 } ) ; // expected-error {{no matching function}}
}
2012-01-18 06:50:08 +08:00
void auto_deduction ( ) {
auto l = { 1 , 2 , 3 , 4 } ;
2015-11-11 09:36:17 +08:00
auto l2 { 1 , 2 , 3 , 4 } ; // expected-error {{initializer for variable 'l2' with type 'auto' contains multiple expressions}}
auto l3 { 1 } ;
2012-01-18 06:50:08 +08:00
static_assert ( same_type < decltype ( l ) , std : : initializer_list < int > > : : value , " " ) ;
2015-11-11 09:36:17 +08:00
static_assert ( same_type < decltype ( l3 ) , int > : : value , " " ) ;
2012-01-18 06:50:08 +08:00
auto bl = { 1 , 2.0 } ; // expected-error {{cannot deduce}}
for ( int i : { 1 , 2 , 3 , 4 } ) { }
}
2012-02-13 02:41:05 +08:00
void dangle ( ) {
new auto { 1 , 2 , 3 } ; // expected-error {{cannot use list-initialization}}
new std : : initializer_list < int > { 1 , 2 , 3 } ; // expected-warning {{at the end of the full-expression}}
}
2012-02-20 00:31:05 +08:00
struct haslist1 {
std : : initializer_list < int > il = { 1 , 2 , 3 } ; // expected-warning{{at the end of the constructor}}
2012-02-22 18:50:08 +08:00
std : : initializer_list < int > jl { 1 , 2 , 3 } ; // expected-warning{{at the end of the constructor}}
2012-02-20 00:31:05 +08:00
haslist1 ( ) ;
} ;
haslist1 : : haslist1 ( )
: il { 1 , 2 , 3 } // expected-warning{{at the end of the constructor}}
{ }
2012-03-16 05:40:51 +08:00
namespace PR12119 {
// Deduction with nested initializer lists.
template < typename T > void f ( std : : initializer_list < T > ) ;
template < typename T > void g ( std : : initializer_list < std : : initializer_list < T > > ) ;
void foo ( ) {
2013-06-13 06:31:48 +08:00
f ( { 0 , { 1 } } ) ; // expected-warning{{braces around scalar initializer}}
2012-03-16 05:40:51 +08:00
g ( { { 0 , 1 } , { 2 , 3 } } ) ;
std : : initializer_list < int > il = { 1 , 2 } ;
g ( { il , { 2 , 3 } } ) ;
}
}
2012-04-04 13:10:53 +08:00
namespace Decay {
template < typename T >
void f ( std : : initializer_list < T > ) {
T x = 1 ; // expected-error{{cannot initialize a variable of type 'const char *' with an rvalue of type 'int'}}
}
void g ( ) {
f ( { " A " , " BB " , " CCC " } ) ; // expected-note{{in instantiation of function template specialization 'Decay::f<const char *>' requested here}}
auto x = { " A " , " BB " , " CCC " } ;
std : : initializer_list < const char * > * il = & x ;
for ( auto s : { " A " , " BB " , " CCC " , " DDD " } ) { }
}
}
2012-04-05 07:09:20 +08:00
namespace PR12436 {
struct X {
template < typename T >
X ( std : : initializer_list < int > , T ) ;
} ;
X x ( { } , 17 ) ;
}
2012-08-01 06:15:04 +08:00
namespace rdar11948732 {
template < typename T > struct X { } ;
struct XCtorInit {
XCtorInit ( std : : initializer_list < X < int > > ) ;
} ;
void f ( X < int > & xi ) {
XCtorInit xc = { xi , xi } ;
}
}
2012-11-07 07:56:42 +08:00
namespace PR14272 {
2015-11-11 09:36:17 +08:00
auto x { { 0 , 0 } } ; // expected-error {{cannot deduce type for variable 'x' with type 'auto' from nested initializer list}}
2012-11-07 07:56:42 +08:00
}
2012-12-09 14:48:56 +08:00
namespace initlist_of_array {
void f ( std : : initializer_list < int [ 2 ] > ) { }
void f ( std : : initializer_list < int [ 2 ] [ 2 ] > ) = delete ;
void h ( ) {
f ( { { 1 , 2 } , { 3 , 4 } } ) ;
}
}
2013-01-31 12:03:12 +08:00
namespace init_list_deduction_failure {
void f ( ) ;
void f ( int ) ;
template < typename T > void g ( std : : initializer_list < T > ) ;
// expected-note@-1 {{candidate template ignored: couldn't resolve reference to overloaded function 'f'}}
void h ( ) { g ( { f } ) ; }
// expected-error@-1 {{no matching function for call to 'g'}}
}
2013-05-24 07:20:04 +08:00
namespace deleted_copy {
struct X {
X ( int i ) { }
X ( const X & x ) = delete ; // expected-note {{here}}
void operator = ( const X & x ) = delete ;
} ;
std : : initializer_list < X > x { 1 } ; // expected-error {{invokes deleted constructor}}
}
2013-09-06 09:22:42 +08:00
namespace RefVersusInitList {
struct S { } ;
void f ( const S & ) = delete ;
void f ( std : : initializer_list < S > ) ;
void g ( S s ) { f ( { S ( ) } ) ; }
}
2013-11-22 07:30:57 +08:00
namespace PR18013 {
int f ( ) ;
std : : initializer_list < long ( * ) ( ) > x = { f } ; // expected-error {{cannot initialize an array element of type 'long (*const)()' with an lvalue of type 'int ()': different return type ('long' vs 'int')}}
}
2014-06-03 16:26:00 +08:00
namespace DR1070 {
struct S {
S ( std : : initializer_list < int > ) ;
} ;
S s [ 3 ] = { { 1 , 2 , 3 } , { 4 , 5 } } ; // ok
S * p = new S [ 3 ] { { 1 , 2 , 3 } , { 4 , 5 } } ; // ok
}
2014-07-17 05:33:43 +08:00
namespace ListInitInstantiate {
struct A {
A ( std : : initializer_list < A > ) ;
2014-07-17 13:12:35 +08:00
A ( std : : initializer_list < int > ) ;
2014-07-17 05:33:43 +08:00
} ;
struct B : A {
B ( int ) ;
} ;
template < typename T > struct X {
X ( ) ;
A a ;
} ;
template < typename T > X < T > : : X ( ) : a { B { 0 } , B { 1 } } { }
X < int > x ;
2014-07-17 13:12:35 +08:00
int f ( const A & ) ;
template < typename T > void g ( ) { int k = f ( { 0 } ) ; }
template void g < int > ( ) ;
2014-07-17 05:33:43 +08:00
}
2015-01-29 06:06:01 +08:00
namespace TemporaryInitListSourceRange_PR22367 {
struct A {
constexpr A ( ) { }
A ( std : : initializer_list < int > ) ; // expected-note {{here}}
} ;
constexpr int f ( A ) { return 0 ; }
constexpr int k = f ( // expected-error {{must be initialized by a constant expression}}
// The point of this test is to check that the caret points to
// 'std::initializer_list', not to '{0}'.
std : : initializer_list // expected-note {{constructor}}
< int >
{ 0 }
) ;
}
2015-06-25 08:25:49 +08:00
namespace ParameterPackNestedInitializerLists_PR23904c3 {
template < typename . . . T >
void f ( std : : initializer_list < std : : initializer_list < T > > . . . tt ) ;
void foo ( ) { f ( { { 0 } } , { { ' \0 ' } } ) ; }
}
2015-12-10 07:18:38 +08:00
namespace update_rbrace_loc_crash {
// We used to crash-on-invalid on this example when updating the right brace
// location.
template < typename T , T >
struct A { } ;
template < typename T , typename F , int . . . I >
std : : initializer_list < T > ExplodeImpl ( F p1 , A < int , I . . . > ) {
// expected-error@+1 {{reference to type 'const update_rbrace_loc_crash::Incomplete' could not bind to an rvalue of type 'void'}}
return { p1 ( I ) . . . } ;
}
template < typename T , int N , typename F >
void Explode ( F p1 ) {
// expected-note@+1 {{in instantiation of function template specialization}}
ExplodeImpl < T > ( p1 , A < int , N > ( ) ) ;
}
class Incomplete ;
struct ContainsIncomplete {
const Incomplete & obstacle ;
} ;
void f ( ) {
// expected-note@+1 {{in instantiation of function template specialization}}
Explode < ContainsIncomplete , 4 > ( [ ] ( int ) { } ) ;
}
}