block-return.c revision 59f5394648e1d86f3df09ce900658199e8bfcb96
1// RUN: clang -fsyntax-only %s -verify
2
3typedef void (^CL)(void);
4
5CL foo() {
6
7	short y;
8
9  short (^add1)(void) = ^{ return y+1; }; // expected-warning {{incompatible block pointer types initializing 'int (^)(void)', expected 'short (^)(void)'}}
10
11	CL X = ^{
12    if (2)
13      return;
14    return 1;  // expected-error {{void block should not return a value}}
15  };
16	int (^Y) (void)  = ^{
17    if (3)
18      return 1;
19    else
20      return; // expected-error {{non-void block should return a value}}
21  };
22
23	char *(^Z)(void) = ^{
24    if (3)
25      return "";
26    else
27      return (char*)0;
28  };
29
30  double (^A)(void) = ^ { // expected-warning {{incompatible block pointer types initializing 'float (^)(void)', expected 'double (^)(void)'}}
31    if (1)
32      return (float)1.0;
33    else
34      if (2)
35       return (double)2.0; // expected-error {{incompatible type returning 'double', expected 'float'}}
36    return 1; // expected-error {{incompatible type returning 'int', expected 'float'}}
37  };
38
39  char *(^B)(void) = ^{
40    if (3)
41      return "";
42    else
43      return 2; // expected-error {{incompatible type returning 'int', expected 'char *'}}
44  };
45  return ^{ return 1; }; // expected-warning {{incompatible block pointer types returning 'int (^)(void)', expected 'CL'}} expected-error {{returning block that lives on the local stack}}
46}
47
48typedef int (^CL2)(void);
49
50CL2 foo2() {
51  return ^{ return 1; }; // expected-error {{returning block that lives on the local stack}}
52}
53
54typedef unsigned int * uintptr_t;
55typedef char Boolean;
56typedef int CFBasicHash;
57
58#define INVOKE_CALLBACK2(P, A, B) (P)(A, B)
59
60typedef struct {
61    Boolean (^isEqual)(const CFBasicHash *, uintptr_t stack_value_or_key1, uintptr_t stack_value_or_key2, Boolean is_key);
62} CFBasicHashCallbacks;
63
64int foo3() {
65    CFBasicHashCallbacks cb;
66
67    Boolean (*value_equal)(uintptr_t, uintptr_t) = 0;
68
69    cb.isEqual = ^(const CFBasicHash *table, uintptr_t stack_value_or_key1, uintptr_t stack_value_or_key2, Boolean is_key) {
70    	return (Boolean)(uintptr_t)INVOKE_CALLBACK2(value_equal, (uintptr_t)stack_value_or_key1, (uintptr_t)stack_value_or_key2);
71    };
72}
73
74static int funk(char *s) {
75  if (^{} == ((void*)0))
76    return 1;
77  else
78    return 0;
79}
80void foo4() {
81  int (^xx)(const char *s) = ^(char *s) { return 1; }; // expected-warning {{incompatible block pointer types initializing 'int (^)(char *)', expected 'int (^)(char const *)'}}
82  int (*yy)(const char *s) = funk; // expected-warning {{incompatible pointer types initializing 'int (char *)', expected 'int (*)(char const *)'}}
83
84  int (^nested)(char *s) = ^(char *str) { void (^nest)(void) = ^(void) { printf("%s\n", str); }; next(); return 1; };
85}
86