1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks
2c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff
3c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Narofftypedef void (^CL)(void);
4c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff
5c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve NaroffCL foo() {
698eb8a7a702b95183ed015706b1f1c66f5cb27a4Mike Stump  short y;
708a41901e18aeb91b87d031b93df70374af02564Douglas Gregor  short (^add1)(void) = ^{ return y+1; }; // expected-error {{incompatible block pointer types initializing 'short (^)(void)' with an expression of type 'int (^)(void)'}}
8c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff
998eb8a7a702b95183ed015706b1f1c66f5cb27a4Mike Stump  CL X = ^{
1098eb8a7a702b95183ed015706b1f1c66f5cb27a4Mike Stump    if (2)
1198eb8a7a702b95183ed015706b1f1c66f5cb27a4Mike Stump      return;
12c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff    return 1;  // expected-error {{void block should not return a value}}
13c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff  };
1498eb8a7a702b95183ed015706b1f1c66f5cb27a4Mike Stump
1598eb8a7a702b95183ed015706b1f1c66f5cb27a4Mike Stump  int (^Y) (void)  = ^{
16c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff    if (3)
17c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff      return 1;
18c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff    else
19c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff      return; // expected-error {{non-void block should return a value}}
20c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff  };
21c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff
2298eb8a7a702b95183ed015706b1f1c66f5cb27a4Mike Stump  char *(^Z)(void) = ^{
23c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff    if (3)
24c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff      return "";
25c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff    else
26c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff      return (char*)0;
27c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff  };
28c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff
2908a41901e18aeb91b87d031b93df70374af02564Douglas Gregor  double (^A)(void) = ^ { // expected-error {{incompatible block pointer types initializing 'double (^)(void)' with an expression of type 'float (^)(void)'}}
3098eb8a7a702b95183ed015706b1f1c66f5cb27a4Mike Stump    if (1)
3198eb8a7a702b95183ed015706b1f1c66f5cb27a4Mike Stump      return (float)1.0;
32c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff    else
33c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff      if (2)
341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return (double)2.0;
3598eb8a7a702b95183ed015706b1f1c66f5cb27a4Mike Stump    return 1;
36c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff  };
3798eb8a7a702b95183ed015706b1f1c66f5cb27a4Mike Stump  char *(^B)(void) = ^{
38c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff    if (3)
39c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff      return "";
40c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff    else
41d4eea8362605807327735727a9098abe1eb23b19Douglas Gregor      return 2; // expected-warning {{incompatible integer to pointer conversion returning 'int' from a function with result type 'char *'}}
42c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff  };
4398eb8a7a702b95183ed015706b1f1c66f5cb27a4Mike Stump
44d4eea8362605807327735727a9098abe1eb23b19Douglas Gregor  return ^{ return 1; }; // expected-error {{incompatible block pointer types returning 'int (^)(void)' from a function with result type 'CL' (aka 'void (^)(void)')}}
45c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff}
46c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff
47c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Narofftypedef int (^CL2)(void);
48c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff
49c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve NaroffCL2 foo2() {
50397195bf3077fb42789b326f69f7d417227a0588Mike Stump  return ^{ return 1; };
51c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff}
5216564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff
5316564420ffe679b0e3cf310c418be6ef98d8e658Steve Narofftypedef unsigned int * uintptr_t;
5416564420ffe679b0e3cf310c418be6ef98d8e658Steve Narofftypedef char Boolean;
5516564420ffe679b0e3cf310c418be6ef98d8e658Steve Narofftypedef int CFBasicHash;
5616564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff
5716564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff#define INVOKE_CALLBACK2(P, A, B) (P)(A, B)
5816564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff
5916564420ffe679b0e3cf310c418be6ef98d8e658Steve Narofftypedef struct {
6016564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff    Boolean (^isEqual)(const CFBasicHash *, uintptr_t stack_value_or_key1, uintptr_t stack_value_or_key2, Boolean is_key);
6116564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff} CFBasicHashCallbacks;
6216564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff
6316564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroffint foo3() {
6416564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff    CFBasicHashCallbacks cb;
6516564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff
6616564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff    Boolean (*value_equal)(uintptr_t, uintptr_t) = 0;
6716564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff
6816564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff    cb.isEqual = ^(const CFBasicHash *table, uintptr_t stack_value_or_key1, uintptr_t stack_value_or_key2, Boolean is_key) {
691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return (Boolean)(uintptr_t)INVOKE_CALLBACK2(value_equal, (uintptr_t)stack_value_or_key1, (uintptr_t)stack_value_or_key2);
7016564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff    };
7116564420ffe679b0e3cf310c418be6ef98d8e658Steve Naroff}
72ba80c9abccd97d9771c1dfa1a862e66ddd4daeddSteve Naroff
73ba80c9abccd97d9771c1dfa1a862e66ddd4daeddSteve Naroffstatic int funk(char *s) {
7459f5394648e1d86f3df09ce900658199e8bfcb96Steve Naroff  if (^{} == ((void*)0))
7559f5394648e1d86f3df09ce900658199e8bfcb96Steve Naroff    return 1;
7659f5394648e1d86f3df09ce900658199e8bfcb96Steve Naroff  else
7759f5394648e1d86f3df09ce900658199e8bfcb96Steve Naroff    return 0;
78ba80c9abccd97d9771c1dfa1a862e66ddd4daeddSteve Naroff}
79e030358cc06e1cbce3c2e00ca67c946f9164b2a8Chris Lattnervoid next();
80ba80c9abccd97d9771c1dfa1a862e66ddd4daeddSteve Naroffvoid foo4() {
8158f9e13e87e57236fee4b914eea9be6f92a1c345Chris Lattner  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 *)'}}
8258f9e13e87e57236fee4b914eea9be6f92a1c345Chris Lattner  int (*yy)(const char *s) = funk; // expected-warning {{incompatible pointer types initializing 'int (*)(const char *)' with an expression of type 'int (char *)'}}
83538afe30e4f9bfb338171be859d584e201dca2dfSteve Naroff
8458f9e13e87e57236fee4b914eea9be6f92a1c345Chris Lattner  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 (const char *, ...)'}} \
85a316e7b735b12ce6b34961a9dcfaae34f4b08d29Douglas Gregor  // expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
86ba80c9abccd97d9771c1dfa1a862e66ddd4daeddSteve Naroff}
87397195bf3077fb42789b326f69f7d417227a0588Mike Stump
88397195bf3077fb42789b326f69f7d417227a0588Mike Stumptypedef void (^bptr)(void);
89397195bf3077fb42789b326f69f7d417227a0588Mike Stump
90397195bf3077fb42789b326f69f7d417227a0588Mike Stumpbptr foo5(int j) {
91397195bf3077fb42789b326f69f7d417227a0588Mike Stump  __block int i;
92397195bf3077fb42789b326f69f7d417227a0588Mike Stump  if (j)
93397195bf3077fb42789b326f69f7d417227a0588Mike Stump    return ^{ ^{ i=0; }(); };  // expected-error {{returning block that lives on the local stack}}
94397195bf3077fb42789b326f69f7d417227a0588Mike Stump  return ^{ i=0; };  // expected-error {{returning block that lives on the local stack}}
954ca606e898293ae58f1793f988500e2218c7a9beChris Lattner  return (^{ i=0; });  // expected-error {{returning block that lives on the local stack}}
964ca606e898293ae58f1793f988500e2218c7a9beChris Lattner  return (void*)(^{ i=0; });  // expected-error {{returning block that lives on the local stack}}
97397195bf3077fb42789b326f69f7d417227a0588Mike Stump}
984eeab84b6527feba5c63b819a74417677c9977a0Mike Stump
994eeab84b6527feba5c63b819a74417677c9977a0Mike Stumpint (*funcptr3[5])(long);
10098650449dc769dd6217f183c846dcaf9e6f94930Argyrios Kyrtzidisint sz8 = sizeof(^int (*[5])(long) {return funcptr3;}); // expected-error {{block cannot return array type}} expected-warning {{incompatible pointer to integer conversion}}
101a4356adfd4a79bd63f86e2b30878795ce7b9b0a6Argyrios Kyrtzidisint sz9 = sizeof(^int(*())()[3]{ }); // expected-error {{function cannot return array type}}
10219c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump
10319c30c00e5e01e4608a43c7deb504f343f09e46dMike Stumpvoid foo6() {
1045d1d7ae120c2c8e6cba5d2a712b33500a5aecc10Anders Carlsson  int (^b)(int) __attribute__((noreturn));
10519c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump  b = ^ (int i) __attribute__((noreturn)) { return 1; };  // expected-error {{block declared 'noreturn' should not return}}
10619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump  b(1);
1075d1d7ae120c2c8e6cba5d2a712b33500a5aecc10Anders Carlsson  int (^c)(void) __attribute__((noreturn)) = ^ __attribute__((noreturn)) { return 100; }; // expected-error {{block declared 'noreturn' should not return}}
10819c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump}
1097d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian
1107d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian
1117d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanianvoid foo7()
1127d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian{
113d263fd1451299b1e5f5f1acb2bb13b0a4119aee8Fariborz Jahanian const int (^BB) (void) = ^{ const int i = 1; return i; }; // OK - initializing 'const int (^)(void)' with an expression of type 'int (^)(void)'
1145291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor
1155495f37302f7c82192dab1ce8d9c9fe76ed0ee37Chandler Carruth const int (^CC) (void)  = ^const int{ const int i = 1; return i; };
1165291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor
1177d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian
1187d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian  int i;
1197d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian  int (^FF) (void)  = ^{ return i; }; // OK
1207d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian  int (^EE) (void)  = ^{ return i+1; }; // OK
1217d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian
1227d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian  __block int j;
1237d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian  int (^JJ) (void)  = ^{ return j; }; // OK
1247d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian  int (^KK) (void)  = ^{ return j+1; }; // OK
1257d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian
1267d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian  __block const int k;
1277d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian  const int cint = 100;
1287d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian
129a873dfc9e7314681bb37efd9ab185045de121e43Douglas Gregor  int (^MM) (void)  = ^{ return k; };
130a873dfc9e7314681bb37efd9ab185045de121e43Douglas Gregor  int (^NN) (void)  = ^{ return cint; };
1317d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian}
1327d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian
1337d5c74ecbbd8719436c071f38657bc8e97ee4a24Fariborz Jahanian
134