2013-07-27 07:45:07 +08:00
// RUN: %clang_cc1 -std=c++11 -Wno-unused-value -fsyntax-only -verify -fblocks %s
// RUN: %clang_cc1 -std=c++1y -Wno-unused-value -fsyntax-only -verify -fblocks %s
2012-01-07 09:08:17 +08:00
2012-01-07 12:59:52 +08:00
namespace std { class type_info ; } ;
2012-01-07 09:08:17 +08:00
namespace ExplicitCapture {
class C {
2012-01-07 12:59:52 +08:00
int Member ;
static void Overload ( int ) ;
void Overload ( ) ;
virtual C & Overload ( float ) ;
2012-01-07 09:08:17 +08:00
2012-01-07 12:59:52 +08:00
void ImplicitThisCapture ( ) {
2012-02-09 16:26:42 +08:00
[ ] ( ) { ( void ) Member ; } ; // expected-error {{'this' cannot be implicitly captured in this context}}
[ & ] ( ) { ( void ) Member ; } ;
[ this ] ( ) { ( void ) Member ; } ;
[ this ] { [ this ] { } ; } ;
[ ] { [ this ] { } ; } ; // expected-error {{'this' cannot be implicitly captured in this context}}
2012-06-05 04:07:46 +08:00
[ ] { Overload ( 3 ) ; } ;
[ ] { Overload ( ) ; } ; // expected-error {{'this' cannot be implicitly captured in this context}}
2012-02-09 16:26:42 +08:00
[ ] { ( void ) typeid ( Overload ( ) ) ; } ;
2012-06-05 04:07:46 +08:00
[ ] { ( void ) typeid ( Overload ( .5f ) ) ; } ; // expected-error {{'this' cannot be implicitly captured in this context}}
2012-01-07 12:59:52 +08:00
}
2012-01-07 09:08:17 +08:00
} ;
void f ( ) {
2012-06-05 04:07:46 +08:00
[ this ] ( ) { } ; // expected-error {{'this' cannot be captured in this context}}
2012-01-07 09:08:17 +08:00
}
}
2012-01-26 11:00:14 +08:00
namespace ReturnDeduction {
void test ( ) {
2012-06-05 04:07:46 +08:00
[ ] ( ) { return 1 ; } ;
[ ] ( ) { return 1 ; } ;
[ ] ( ) { return ( { return 1 ; 1 ; } ) ; } ;
[ ] ( ) { return ( { return ' c ' ; 1 ; } ) ; } ; // expected-error {{must match previous return type}}
[ ] ( ) - > int { return ' c ' ; return 1 ; } ;
2012-02-09 16:26:42 +08:00
[ ] ( ) { return ' c ' ; return 1 ; } ; // expected-error {{must match previous return type}}
2012-06-05 04:07:46 +08:00
[ ] ( ) { return ; return ( void ) 0 ; } ;
[ ] ( ) { return 1 ; return 1 ; } ;
2012-01-26 11:00:14 +08:00
}
}
2012-02-04 06:47:37 +08:00
namespace ImplicitCapture {
void test ( ) {
2012-02-04 07:06:43 +08:00
int a = 0 ; // expected-note 5 {{declared}}
2012-06-05 04:07:46 +08:00
[ ] ( ) { return a ; } ; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{begins here}}
[ & ] ( ) { return a ; } ;
[ = ] ( ) { return a ; } ;
[ = ] ( ) { int * b = & a ; } ; // expected-error {{cannot initialize a variable of type 'int *' with an rvalue of type 'const int *'}}
2012-02-09 16:26:42 +08:00
[ = ] ( ) { return [ & ] ( ) { return a ; } ; } ;
2012-06-05 04:07:46 +08:00
[ ] ( ) { return [ & ] ( ) { return a ; } ; } ; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
[ ] ( ) { return ^ { return a ; } ; } ; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
[ ] ( ) { return [ & a ] { return a ; } ; } ; // expected-error 2 {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note 2 {{lambda expression begins here}}
[ = ] ( ) { return [ & a ] { return a ; } ; } ; //
2012-02-04 06:47:37 +08:00
const int b = 2 ;
2012-06-05 04:07:46 +08:00
[ ] ( ) { return b ; } ;
2012-02-04 06:47:37 +08:00
union { // expected-note {{declared}}
int c ;
float d ;
} ;
d = 3 ;
2012-06-05 04:07:46 +08:00
[ = ] ( ) { return c ; } ; // expected-error {{unnamed variable cannot be implicitly captured in a lambda expression}}
2012-02-04 06:47:37 +08:00
2012-02-04 07:06:43 +08:00
__block int e ; // expected-note 3 {{declared}}
2012-06-05 04:07:46 +08:00
[ & ] ( ) { return e ; } ; // expected-error {{__block variable 'e' cannot be captured in a lambda expression}}
[ & e ] ( ) { return e ; } ; // expected-error 2 {{__block variable 'e' cannot be captured in a lambda expression}}
2012-02-04 06:47:37 +08:00
int f [ 10 ] ; // expected-note {{declared}}
2012-06-05 04:07:46 +08:00
[ & ] ( ) { return f [ 2 ] ; } ;
2012-02-13 02:42:33 +08:00
( void ) ^ { return [ ] ( ) { return f [ 2 ] ; } ; } ; / / expected - error { { variable ' f ' cannot be implicitly captured in a lambda with no capture - default specified } } \
// expected-note{{lambda expression begins here}}
2012-02-04 06:47:37 +08:00
struct G { G ( ) ; G ( G & ) ; int a ; } ; // expected-note 6 {{not viable}}
G g ;
2012-06-05 04:07:46 +08:00
[ = ] ( ) { const G * gg = & g ; return gg - > a ; } ;
2012-10-25 04:28:18 +08:00
[ = ] ( ) { return [ = ] { const G * gg = & g ; return gg - > a ; } ( ) ; } ; // expected-error {{no matching constructor for initialization of 'G'}}
( void ) ^ { return [ = ] { const G * gg = & g ; return gg - > a ; } ( ) ; } ; // expected-error 2 {{no matching constructor for initialization of 'const G'}}
2012-02-07 05:50:18 +08:00
const int h = a ; // expected-note {{declared}}
2012-06-05 04:07:46 +08:00
[ ] ( ) { return h ; } ; // expected-error {{variable 'h' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
2012-03-02 12:14:40 +08:00
2012-10-20 09:38:33 +08:00
// References can appear in constant expressions if they are initialized by
// reference constant expressions.
int i ;
int & ref_i = i ; // expected-note {{declared}}
2012-03-02 12:14:40 +08:00
[ ] { return ref_i ; } ; // expected-error {{variable 'ref_i' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
2012-10-20 09:38:33 +08:00
static int j ;
int & ref_j = j ;
[ ] { return ref_j ; } ; // ok
2012-02-04 06:47:37 +08:00
}
}
2012-02-22 04:05:31 +08:00
namespace PR12031 {
struct X {
template < typename T >
X ( const T & ) ;
~ X ( ) ;
} ;
void f ( int i , X x ) ;
void g ( ) {
const int v = 10 ;
f ( v , [ ] ( ) { } ) ;
}
}
2012-02-25 06:12:32 +08:00
2013-06-13 10:46:14 +08:00
namespace Array {
2012-02-25 06:12:32 +08:00
int & f ( int * p ) ;
char & f ( . . . ) ;
void g ( ) {
2013-06-13 10:46:14 +08:00
int n = - 1 ;
2012-02-25 06:12:32 +08:00
[ = ] {
2013-06-13 10:46:14 +08:00
int arr [ n ] ; // VLA
2012-02-25 06:12:32 +08:00
} ( ) ;
2013-06-13 10:46:14 +08:00
const int m = - 1 ;
[ ] {
int arr [ m ] ; // expected-error{{negative size}}
2012-02-25 06:12:32 +08:00
} ( ) ;
2013-06-13 10:46:14 +08:00
[ & ] {
int arr [ m ] ; // expected-error{{negative size}}
} ( ) ;
[ = ] {
int arr [ m ] ; // expected-error{{negative size}}
2012-02-25 06:12:32 +08:00
} ( ) ;
[ m ] {
2013-06-13 10:46:14 +08:00
int arr [ m ] ; // expected-error{{negative size}}
2012-02-25 06:12:32 +08:00
} ( ) ;
}
}
2012-03-13 04:57:19 +08:00
void PR12248 ( )
{
unsigned int result = 0 ;
auto l = [ & ] ( ) { + + result ; } ;
}
2012-03-13 08:37:01 +08:00
namespace ModifyingCapture {
void test ( ) {
int n = 0 ;
[ = ] {
2012-03-13 09:10:51 +08:00
n = 1 ; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
2012-03-13 08:37:01 +08:00
} ;
}
}
2012-07-25 11:56:55 +08:00
namespace VariadicPackExpansion {
template < typename T , typename U > using Fst = T ;
template < typename . . . Ts > bool g ( Fst < bool , Ts > . . . bools ) ;
template < typename . . . Ts > bool f ( Ts & & . . . ts ) {
return g < Ts . . . > ( [ & ts ] {
if ( ! ts )
return false ;
- - ts ;
return true ;
} ( ) . . . ) ;
}
void h ( ) {
int a = 5 , b = 2 , c = 3 ;
while ( f ( a , b , c ) ) {
}
}
struct sink {
template < typename . . . Ts > sink ( Ts & & . . . ) { }
} ;
template < typename . . . Ts > void local_class ( ) {
sink {
[ ] ( Ts t ) {
struct S : Ts {
void f ( Ts t ) {
Ts & that = * this ;
that = t ;
}
Ts g ( ) { return * this ; } ;
} ;
S s ;
s . f ( t ) ;
return s ;
} ( Ts ( ) ) . g ( ) . . .
} ;
} ;
struct X { } ; struct Y { } ;
template void local_class < X , Y > ( ) ;
template < typename . . . Ts > void nested ( Ts . . . ts ) {
f (
// Each expansion of this lambda implicitly captures all of 'ts', because
// the inner lambda also expands 'ts'.
[ & ] {
return ts + [ & ] { return f ( ts . . . ) ; } ( ) ;
} ( ) . . .
) ;
}
template void nested ( int , int , int ) ;
template < typename . . . Ts > void nested2 ( Ts . . . ts ) { // expected-note 2{{here}}
// Capture all 'ts', use only one.
f ( [ & ts . . . ] { return ts ; } ( ) . . . ) ;
// Capture each 'ts', use it.
f ( [ & ts ] { return ts ; } ( ) . . . ) ;
// Capture all 'ts', use all of them.
f ( [ & ts . . . ] { return ( int ) f ( ts . . . ) ; } ( ) ) ;
// Capture each 'ts', use all of them. Ill-formed. In more detail:
//
// We instantiate two lambdas here; the first captures ts$0, the second
// captures ts$1. Both of them reference both ts parameters, so both are
// ill-formed because ts can't be implicitly captured.
//
// FIXME: This diagnostic does not explain what's happening. We should
// specify which 'ts' we're referring to in its diagnostic name. We should
// also say which slice of the pack expansion is being performed in the
// instantiation backtrace.
f ( [ & ts ] { return ( int ) f ( ts . . . ) ; } ( ) . . . ) ; / / \
/ / expected - error 2 { { ' ts ' cannot be implicitly captured } } \
// expected-note 2{{lambda expression begins here}}
}
template void nested2 ( int ) ; // ok
template void nested2 ( int , int ) ; // expected-note {{in instantiation of}}
}
2012-09-19 05:11:30 +08:00
namespace PR13860 {
void foo ( ) {
auto x = PR13860UndeclaredIdentifier ( ) ; // expected-error {{use of undeclared identifier 'PR13860UndeclaredIdentifier'}}
auto y = [ x ] ( ) { } ;
static_assert ( sizeof ( y ) , " " ) ;
}
}
2012-09-20 09:40:23 +08:00
namespace PR13854 {
auto l = [ ] ( void ) { } ;
}
2012-12-06 23:42:21 +08:00
namespace PR14518 {
auto f = [ ] ( void ) { return __func__ ; } ; // no-warning
}
2013-07-27 06:53:54 +08:00
namespace PR16708 {
auto L = [ ] ( ) {
auto ret = 0 ;
return ret ;
return 0 ;
} ;
}
2013-07-27 07:45:07 +08:00
namespace TypeDeduction {
struct S { } ;
void f ( ) {
const S s { } ;
S & & t = [ & ] { return s ; } ( ) ;
2014-12-20 06:10:51 +08:00
# if __cplusplus > 201103L
2013-07-27 07:45:07 +08:00
S & & u = [ & ] ( ) - > auto { return s ; } ( ) ;
# endif
}
}
2013-10-01 10:51:53 +08:00
namespace lambdas_in_NSDMIs {
template < class T >
struct L {
T t { } ;
T t2 = ( [ ] ( int a ) { return [ ] ( int b ) { return b ; } ; } ) ( t ) ( t ) ;
} ;
L < int > l ;
namespace non_template {
struct L {
int t = 0 ;
int t2 = ( [ ] ( int a ) { return [ ] ( int b ) { return b ; } ; } ) ( t ) ( t ) ;
} ;
L l ;
}
2014-01-17 11:11:34 +08:00
}
// PR18477: don't try to capture 'this' from an NSDMI encountered while parsing
// a lambda.
namespace NSDMIs_in_lambdas {
template < typename T > struct S { int a = 0 ; int b = a ; } ;
void f ( ) { [ ] ( ) { S < int > s ; } ; }
auto x = [ ] { struct S { int n , m = n ; } ; } ;
2014-02-07 05:49:08 +08:00
auto y = [ & ] { struct S { int n , m = n ; } ; } ; // expected-error {{non-local lambda expression cannot have a capture-default}}
2014-01-17 11:11:34 +08:00
void g ( ) { auto z = [ & ] { struct S { int n , m = n ; } ; } ; }
}
2014-01-22 07:27:46 +08:00
namespace CaptureIncomplete {
struct Incomplete ; // expected-note 2{{forward decl}}
void g ( const Incomplete & a ) ;
void f ( Incomplete & a ) {
( void ) [ a ] { } ; // expected-error {{incomplete}}
( void ) [ & a ] { } ;
( void ) [ = ] { g ( a ) ; } ; // expected-error {{incomplete}}
( void ) [ & ] { f ( a ) ; } ;
}
}
namespace CaptureAbstract {
struct S {
virtual void f ( ) = 0 ; // expected-note {{unimplemented}}
int n = 0 ;
} ;
struct T : S {
constexpr T ( ) { }
void f ( ) ;
} ;
void f ( ) {
constexpr T t = T ( ) ;
S & s = const_cast < T & > ( t ) ;
// FIXME: Once we properly compute odr-use per DR712, this should be
// accepted (and should not capture 's').
[ = ] { return s . n ; } ; // expected-error {{abstract}}
}
}
2014-02-07 05:49:08 +08:00
namespace PR18128 {
auto l = [ = ] { } ; // expected-error {{non-local lambda expression cannot have a capture-default}}
struct S {
int n ;
int ( * f ( ) ) [ true ? 1 : ( [ = ] { return n ; } ( ) , 0 ) ] ;
// expected-error@-1 {{non-local lambda expression cannot have a capture-default}}
// expected-error@-2 {{invalid use of non-static data member 'n'}}
// expected-error@-3 {{a lambda expression may not appear inside of a constant expression}}
int g ( int k = ( [ = ] { return n ; } ( ) , 0 ) ) ;
// expected-error@-1 {{non-local lambda expression cannot have a capture-default}}
// expected-error@-2 {{invalid use of non-static data member 'n'}}
int a = [ = ] { return n ; } ( ) ; // ok
int b = [ = ] { return [ = ] { return n ; } ( ) ; } ( ) ; // ok
int c = [ ] { int k = 0 ; return [ = ] { return k ; } ( ) ; } ( ) ; // ok
int d = [ ] { return [ = ] { return n ; } ( ) ; } ( ) ; // expected-error {{'this' cannot be implicitly captured in this context}}
} ;
}
2014-02-07 07:35:16 +08:00
namespace PR18473 {
template < typename T > void f ( ) {
T t ( 0 ) ;
( void ) [ = ] { int n = t ; } ; // expected-error {{deleted}}
}
template void f < int > ( ) ;
struct NoCopy {
NoCopy ( int ) ;
NoCopy ( const NoCopy & ) = delete ; // expected-note {{deleted}}
operator int ( ) const ;
} ;
template void f < NoCopy > ( ) ; // expected-note {{instantiation}}
}
2014-03-26 05:11:32 +08:00
void PR19249 ( ) {
auto x = [ & x ] { } ; // expected-error {{cannot appear in its own init}}
}
2014-09-03 03:32:44 +08:00
namespace PR20731 {
template < class L , int X = sizeof ( L ) >
void Job ( L l ) ;
template < typename . . . Args >
void Logger ( Args & & . . . args ) {
auto len = Invalid_Function ( ( args ) . . . ) ;
// expected-error@-1 {{use of undeclared identifier 'Invalid_Function'}}
Job ( [ len ] ( ) { } ) ;
}
void GetMethod ( ) {
Logger ( ) ;
// expected-note@-1 {{in instantiation of function template specialization 'PR20731::Logger<>' requested here}}
}
template < typename T >
struct A {
T t ;
// expected-error@-1 {{field has incomplete type 'void'}}
} ;
template < typename F >
void g ( F f ) {
auto a = A < decltype ( f ( ) ) > { } ;
// expected-note@-1 {{in instantiation of template class 'PR20731::A<void>' requested here}}
auto xf = [ a , f ] ( ) { } ;
int x = sizeof ( xf ) ;
} ;
void f ( ) {
g ( [ ] { } ) ;
// expected-note-re@-1 {{in instantiation of function template specialization 'PR20731::g<(lambda at {{.*}}>' requested here}}
}
template < class _Rp > struct function {
template < class _Fp >
function ( _Fp ) {
static_assert ( sizeof ( _Fp ) > 0 , " Type must be complete. " ) ;
}
} ;
template < typename T > void p ( T t ) {
auto l = some_undefined_function ( t ) ;
// expected-error@-1 {{use of undeclared identifier 'some_undefined_function'}}
function < void ( ) > ( ( [ l ] ( ) { } ) ) ;
}
void q ( ) { p ( 0 ) ; }
// expected-note@-1 {{in instantiation of function template specialization 'PR20731::p<int>' requested here}}
}
2014-11-21 07:00:25 +08:00
namespace lambda_in_default_mem_init {
template < typename T > void f ( ) {
struct S { int n = [ ] { return 0 ; } ( ) ; } ;
}
template void f < int > ( ) ;
2014-11-21 07:53:14 +08:00
template < typename T > void g ( ) {
struct S { int n = [ ] ( int n ) { return n ; } ( 0 ) ; } ;
}
template void g < int > ( ) ;
2014-11-21 07:00:25 +08:00
}
2014-12-16 05:07:16 +08:00
namespace error_in_transform_prototype {
template < class T >
void f ( T t ) {
// expected-error@+2 {{type 'int' cannot be used prior to '::' because it has no members}}
// expected-error@+1 {{no member named 'ns' in 'error_in_transform_prototype::S'}}
auto x = [ ] ( typename T : : ns : : type & k ) { } ;
}
class S { } ;
void foo ( ) {
f ( 5 ) ; // expected-note {{requested here}}
f ( S ( ) ) ; // expected-note {{requested here}}
}
}
2015-02-11 09:48:47 +08:00
namespace PR21857 {
template < typename Fn > struct fun : Fn {
fun ( ) = default ;
using Fn : : operator ( ) ;
} ;
template < typename Fn > fun < Fn > wrap ( Fn fn ) ;
auto x = wrap ( [ ] ( ) { } ) ;
}