2020-02-16 22:01:25 +08:00
// RUN: %clang_cc1 -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -pedantic -fsyntax-only %s -verify -fblocks
2008-09-17 06:25:10 +08:00
typedef void ( ^ CL ) ( void ) ;
CL foo ( ) {
2009-02-05 06:31:32 +08:00
short y ;
2010-04-10 01:53:29 +08:00
short ( ^ add1 ) ( void ) = ^ { return y + 1 ; } ; // expected-error {{incompatible block pointer types initializing 'short (^)(void)' with an expression of type 'int (^)(void)'}}
2008-09-17 06:25:10 +08:00
2009-02-05 06:31:32 +08:00
CL X = ^ {
if ( 2 )
return ;
2011-12-04 07:53:56 +08:00
return 1 ; // expected-error {{return type 'int' must match previous return type 'void' when block literal has unspecified explicit return type}}
2008-09-17 06:25:10 +08:00
} ;
2009-02-05 06:31:32 +08:00
int ( ^ Y ) ( void ) = ^ {
2008-09-17 06:25:10 +08:00
if ( 3 )
return 1 ;
else
2011-12-04 07:53:56 +08:00
return ; // expected-error {{return type 'void' must match previous return type 'int' when block literal has unspecified explicit return type}}
2008-09-17 06:25:10 +08:00
} ;
2009-02-05 06:31:32 +08:00
char * ( ^ Z ) ( void ) = ^ {
2008-09-17 06:25:10 +08:00
if ( 3 )
return " " ;
else
return ( char * ) 0 ;
} ;
2010-04-10 01:53:29 +08:00
double ( ^ A ) ( void ) = ^ { // expected-error {{incompatible block pointer types initializing 'double (^)(void)' with an expression of type 'float (^)(void)'}}
2009-02-05 06:31:32 +08:00
if ( 1 )
return ( float ) 1.0 ;
2008-09-17 06:25:10 +08:00
else
if ( 2 )
2011-12-04 01:47:53 +08:00
return ( double ) 2.0 ; // expected-error {{return type 'double' must match previous return type 'float' when block literal has unspecified explicit return type}}
return 1 ; // expected-error {{return type 'int' must match previous return type 'float' when block literal has unspecified explicit return type}}
2008-09-17 06:25:10 +08:00
} ;
2009-02-05 06:31:32 +08:00
char * ( ^ B ) ( void ) = ^ {
2008-09-17 06:25:10 +08:00
if ( 3 )
return " " ;
else
2011-12-04 01:47:53 +08:00
return 2 ; // expected-error {{return type 'int' must match previous return type 'char *' when block literal has unspecified explicit return type}}
2008-09-17 06:25:10 +08:00
} ;
2009-02-05 06:31:32 +08:00
2010-04-09 08:35:39 +08:00
return ^ { return 1 ; } ; // expected-error {{incompatible block pointer types returning 'int (^)(void)' from a function with result type 'CL' (aka 'void (^)(void)')}}
2008-09-17 06:25:10 +08:00
}
typedef int ( ^ CL2 ) ( void ) ;
CL2 foo2 ( ) {
2009-04-17 08:09:41 +08:00
return ^ { return 1 ; } ;
2008-09-17 06:25:10 +08:00
}
2008-09-25 06:26:48 +08:00
typedef unsigned int * uintptr_t ;
typedef char Boolean ;
typedef int CFBasicHash ;
# define INVOKE_CALLBACK2(P, A, B) (P)(A, B)
typedef struct {
Boolean ( ^ isEqual ) ( const CFBasicHash * , uintptr_t stack_value_or_key1 , uintptr_t stack_value_or_key2 , Boolean is_key ) ;
} CFBasicHashCallbacks ;
int foo3 ( ) {
CFBasicHashCallbacks cb ;
Boolean ( * value_equal ) ( uintptr_t , uintptr_t ) = 0 ;
cb . isEqual = ^ ( const CFBasicHash * table , uintptr_t stack_value_or_key1 , uintptr_t stack_value_or_key2 , Boolean is_key ) {
2009-09-09 23:08:12 +08:00
return ( Boolean ) ( uintptr_t ) INVOKE_CALLBACK2 ( value_equal , ( uintptr_t ) stack_value_or_key1 , ( uintptr_t ) stack_value_or_key2 ) ;
2008-09-25 06:26:48 +08:00
} ;
}
2008-09-25 07:31:10 +08:00
static int funk ( char * s ) {
2008-09-28 09:11:11 +08:00
if ( ^ { } = = ( ( void * ) 0 ) )
return 1 ;
else
return 0 ;
2008-09-25 07:31:10 +08:00
}
2010-01-10 04:43:19 +08:00
void next ( ) ;
2008-09-25 07:31:10 +08:00
void foo4 ( ) {
2010-09-05 08:04:01 +08:00
int ( ^ xx ) ( const char * s ) = ^ ( char * s ) { return 1 ; } ; // expected-error {{incompatible block pointer types initializing 'int (^)(const char *)' with an expression of type 'int (^)(char *)'}}
2020-02-25 22:49:59 +08:00
int ( * yy ) ( const char * s ) = funk ; // expected-warning {{incompatible function pointer types initializing 'int (*)(const char *)' with an expression of type 'int (char *)'}}
2008-09-28 08:13:36 +08:00
2012-01-28 07:21:02 +08:00
int ( ^ nested ) ( char * s ) = ^ ( char * str ) { void ( ^ nest ) ( void ) = ^ ( void ) { printf ( " %s \n " , str ) ; } ; next ( ) ; return 1 ; } ; / / expected - warning { { implicitly declaring library function ' printf ' with type ' int ( const char * , . . . ) ' } } \
2014-07-12 04:53:51 +08:00
// expected-note{{include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
2008-09-25 07:31:10 +08:00
}
2009-04-17 08:09:41 +08:00
typedef void ( ^ bptr ) ( void ) ;
bptr foo5 ( int j ) {
__block int i ;
if ( j )
return ^ { ^ { i = 0 ; } ( ) ; } ; // expected-error {{returning block that lives on the local stack}}
return ^ { i = 0 ; } ; // expected-error {{returning block that lives on the local stack}}
2009-09-08 08:36:37 +08:00
return ( ^ { i = 0 ; } ) ; // expected-error {{returning block that lives on the local stack}}
return ( void * ) ( ^ { i = 0 ; } ) ; // expected-error {{returning block that lives on the local stack}}
2009-04-17 08:09:41 +08:00
}
2009-04-28 09:10:27 +08:00
int ( * funcptr3 [ 5 ] ) ( long ) ;
2011-01-26 07:16:33 +08:00
int sz8 = sizeof ( ^ int ( * [ 5 ] ) ( long ) { return funcptr3 ; } ) ; // expected-error {{block cannot return array type}} expected-warning {{incompatible pointer to integer conversion}}
2011-01-26 09:26:44 +08:00
int sz9 = sizeof ( ^ int ( * ( ) ) ( ) [ 3 ] { } ) ; // expected-error {{function cannot return array type}}
2009-04-30 03:03:13 +08:00
void foo6 ( ) {
2010-09-03 08:25:02 +08:00
int ( ^ b ) ( int ) __attribute__ ( ( noreturn ) ) ;
2009-04-30 03:03:13 +08:00
b = ^ ( int i ) __attribute__ ( ( noreturn ) ) { return 1 ; } ; // expected-error {{block declared 'noreturn' should not return}}
b ( 1 ) ;
2010-09-03 08:25:02 +08:00
int ( ^ c ) ( void ) __attribute__ ( ( noreturn ) ) = ^ __attribute__ ( ( noreturn ) ) { return 100 ; } ; // expected-error {{block declared 'noreturn' should not return}}
2009-04-30 03:03:13 +08:00
}
2009-06-20 07:37:08 +08:00
void foo7 ( )
{
2011-02-12 02:46:17 +08:00
const int ( ^ BB ) ( void ) = ^ { const int i = 1 ; return i ; } ; // OK - initializing 'const int (^)(void)' with an expression of type 'int (^)(void)'
2010-07-13 16:18:22 +08:00
2010-07-14 14:36:18 +08:00
const int ( ^ CC ) ( void ) = ^ const int { const int i = 1 ; return i ; } ;
2010-07-13 16:18:22 +08:00
2009-06-20 07:37:08 +08:00
int i ;
int ( ^ FF ) ( void ) = ^ { return i ; } ; // OK
int ( ^ EE ) ( void ) = ^ { return i + 1 ; } ; // OK
__block int j ;
int ( ^ JJ ) ( void ) = ^ { return j ; } ; // OK
int ( ^ KK ) ( void ) = ^ { return j + 1 ; } ; // OK
__block const int k ;
const int cint = 100 ;
2010-02-03 08:27:59 +08:00
int ( ^ MM ) ( void ) = ^ { return k ; } ;
int ( ^ NN ) ( void ) = ^ { return cint ; } ;
2009-06-20 07:37:08 +08:00
}
2012-03-22 00:45:13 +08:00
// rdar://11069896
void ( ^ blk ) ( void ) = ^ {
2012-03-22 04:28:39 +08:00
return ( void ) 0 ; // expected-warning {{void block literal should not return void expression}}
2012-03-22 00:45:13 +08:00
} ;
2013-03-21 08:10:07 +08:00
// rdar://13463504
enum Test8 { T8_a , T8_b , T8_c } ;
void test8 ( void ) {
extern void test8_helper ( int ( ^ ) ( int ) ) ;
test8_helper ( ^ ( int flag ) { if ( flag ) return T8_a ; return T8_b ; } ) ;
}
void test8b ( void ) {
extern void test8_helper2 ( char ( ^ ) ( int ) ) ; // expected-note {{here}}
test8_helper2 ( ^ ( int flag ) { if ( flag ) return T8_a ; return T8_b ; } ) ; // expected-error {{passing 'enum Test8 (^)(int)' to parameter of type 'char (^)(int)'}}
}