2008-12-05 07:20:07 +08:00
// RUN: clang -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 ;
2008-09-25 07:31:10 +08:00
short ( ^ add1 ) ( void ) = ^ { return y + 1 ; } ; // expected-warning {{incompatible block pointer types initializing 'int (^)(void)', expected 'short (^)(void)'}}
2008-09-17 06:25:10 +08:00
2009-02-05 06:31:32 +08:00
CL X = ^ {
if ( 2 )
return ;
2008-09-17 06:25:10 +08:00
return 1 ; // expected-error {{void block should not return a value}}
} ;
2009-02-05 06:31:32 +08:00
int ( ^ Y ) ( void ) = ^ {
2008-09-17 06:25:10 +08:00
if ( 3 )
return 1 ;
else
return ; // expected-error {{non-void block should return a value}}
} ;
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 ;
} ;
2008-09-25 07:31:10 +08:00
double ( ^ A ) ( void ) = ^ { // expected-warning {{incompatible block pointer types initializing 'float (^)(void)', expected 'double (^)(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 )
2009-02-05 06:31:32 +08:00
return ( double ) 2.0 ;
return 1 ;
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
2009-02-05 06:31:32 +08:00
return 2 ; // expected-warning {{incompatible integer to pointer conversion returning 'int', expected 'char *'}}
2008-09-17 06:25:10 +08:00
} ;
2009-02-05 06:31:32 +08:00
2008-09-25 07:31:10 +08:00
return ^ { return 1 ; } ; // expected-warning {{incompatible block pointer types returning 'int (^)(void)', expected 'CL'}} expected-error {{returning block that lives on the local stack}}
2008-09-17 06:25:10 +08:00
}
typedef int ( ^ CL2 ) ( void ) ;
CL2 foo2 ( ) {
return ^ { return 1 ; } ; // expected-error {{returning block that lives on the local stack}}
}
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 ) {
return ( Boolean ) ( uintptr_t ) INVOKE_CALLBACK2 ( value_equal , ( uintptr_t ) stack_value_or_key1 , ( uintptr_t ) stack_value_or_key2 ) ;
} ;
}
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
}
void foo4 ( ) {
int ( ^ xx ) ( const char * s ) = ^ ( char * s ) { return 1 ; } ; // expected-warning {{incompatible block pointer types initializing 'int (^)(char *)', expected 'int (^)(char const *)'}}
int ( * yy ) ( const char * s ) = funk ; // expected-warning {{incompatible pointer types initializing 'int (char *)', expected 'int (*)(char const *)'}}
2008-09-28 08:13:36 +08:00
2009-02-14 08:32:47 +08:00
int ( ^ nested ) ( char * s ) = ^ ( char * str ) { void ( ^ nest ) ( void ) = ^ ( void ) { printf ( " %s \n " , str ) ; } ; next ( ) ; return 1 ; } ; / / expected - warning { { implicitly declaring C library function ' printf ' with type ' int ( char const * , . . . ) ' } } \
// expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
2008-09-25 07:31:10 +08:00
}