block-misc.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
  2. void donotwarn();
  3. int (^IFP) ();
  4. int (^II) (int);
  5. int test1() {
  6. int (^PFR) (int) = 0; // OK
  7. PFR = II; // OK
  8. if (PFR == II) // OK
  9. donotwarn();
  10. if (PFR == IFP) // OK
  11. donotwarn();
  12. if (PFR == (int (^) (int))IFP) // OK
  13. donotwarn();
  14. if (PFR == 0) // OK
  15. donotwarn();
  16. if (PFR) // OK
  17. donotwarn();
  18. if (!PFR) // OK
  19. donotwarn();
  20. return PFR != IFP; // OK
  21. }
  22. int test2(double (^S)()) {
  23. double (^I)(int) = (void*) S;
  24. (void*)I = (void *)S; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}}
  25. void *pv = I;
  26. pv = S;
  27. I(1);
  28. return (void*)I == (void *)S;
  29. }
  30. int^ x; // expected-error {{block pointer to non-function type is invalid}}
  31. int^^ x1; // expected-error {{block pointer to non-function type is invalid}} expected-error {{block pointer to non-function type is invalid}}
  32. void test3() {
  33. char *^ y; // expected-error {{block pointer to non-function type is invalid}}
  34. }
  35. enum {NSBIRLazilyAllocated = 0};
  36. int test4(int argc) { // rdar://6251437
  37. ^{
  38. switch (argc) {
  39. case NSBIRLazilyAllocated: // is an integer constant expression.
  40. default:
  41. break;
  42. }
  43. }();
  44. return 0;
  45. }
  46. void bar(void*);
  47. // rdar://6257721 - reference to static/global is byref by default.
  48. static int test5g;
  49. void test5() {
  50. bar(^{ test5g = 1; });
  51. }
  52. // rdar://6405429 - __func__ in a block refers to the containing function name.
  53. const char*test6() {
  54. return ^{
  55. return __func__;
  56. } ();
  57. }
  58. // radr://6732116 - block comparisons
  59. void (^test7a)();
  60. int test7(void (^p)()) {
  61. return test7a == p;
  62. }
  63. void test8() {
  64. somelabel:
  65. ^{ goto somelabel; }(); // expected-error {{use of undeclared label 'somelabel'}}
  66. }
  67. void test9() {
  68. goto somelabel; // expected-error {{use of undeclared label 'somelabel'}}
  69. ^{ somelabel: ; }();
  70. }
  71. void test10(int i) {
  72. switch (i) {
  73. case 41: ;
  74. ^{ case 42: ; }(); // expected-error {{'case' statement not in switch statement}}
  75. }
  76. }
  77. void test11(int i) {
  78. switch (i) {
  79. case 41: ;
  80. ^{ break; }(); // expected-error {{'break' statement not in loop or switch statement}}
  81. }
  82. for (; i < 100; ++i)
  83. ^{ break; }(); // expected-error {{'break' statement not in loop or switch statement}}
  84. }
  85. void (^test12f)(void);
  86. void test12() {
  87. test12f = ^test12f; // expected-error {{type name requires a specifier or qualifier}} expected-error {{expected expression}}
  88. }
  89. // rdar://6808730
  90. void *test13 = ^{
  91. int X = 32;
  92. void *P = ^{
  93. return X+4; // References outer block's "X", so outer block is constant.
  94. };
  95. };
  96. void test14() {
  97. int X = 32;
  98. static void *P = ^{ // expected-error {{initializer element is not a compile-time constant}}
  99. void *Q = ^{
  100. // References test14's "X": outer block is non-constant.
  101. return X+4;
  102. };
  103. };
  104. }
  105. enum { LESS };
  106. void foo(long (^comp)()) { // expected-note{{passing argument to parameter 'comp' here}}
  107. }
  108. void (^test15f)(void);
  109. void test15() {
  110. foo(^{ return LESS; }); // expected-error {{incompatible block pointer types passing 'int (^)(void)' to parameter of type 'long (^)()'}}
  111. }
  112. __block int test16i; // expected-error {{__block attribute not allowed, only allowed on local variables}}
  113. void test16(__block int i) { // expected-error {{__block attribute not allowed, only allowed on local variables}}
  114. int size = 5;
  115. extern __block double extern_var; // expected-error {{__block attribute not allowed, only allowed on local variables}}
  116. static __block char * pch; // expected-error {{__block attribute not allowed, only allowed on local variables}}
  117. __block int a[size]; // expected-error {{__block attribute not allowed on declaration with a variably modified type}}
  118. __block int (*ap)[size]; // expected-error {{__block attribute not allowed on declaration with a variably modified type}}
  119. }
  120. void f();
  121. void test17() {
  122. void (^bp)(int);
  123. void (*rp)(int);
  124. void (^bp1)();
  125. void *vp = bp;
  126. f(1 ? bp : vp);
  127. f(1 ? vp : bp);
  128. f(1 ? bp : bp1);
  129. (void)(bp > rp); // expected-error {{invalid operands}}
  130. (void)(bp > 0); // expected-error {{invalid operands}}
  131. (void)(bp > bp); // expected-error {{invalid operands}}
  132. (void)(bp > vp); // expected-error {{invalid operands}}
  133. f(1 ? bp : rp); // expected-error {{incompatible operand types ('void (^)(int)' and 'void (*)(int)')}}
  134. (void)(bp == 1); // expected-error {{invalid operands to binary expression}}
  135. (void)(bp == 0);
  136. (void)(1 == bp); // expected-error {{invalid operands to binary expression}}
  137. (void)(0 == bp);
  138. (void)(bp < 1); // expected-error {{invalid operands to binary expression}}
  139. (void)(bp < 0); // expected-error {{invalid operands to binary expression}}
  140. (void)(1 < bp); // expected-error {{invalid operands to binary expression}}
  141. (void)(0 < bp); // expected-error {{invalid operands to binary expression}}
  142. }
  143. void test18() {
  144. void (^const blockA)(void) = ^{ }; // expected-note {{variable 'blockA' declared const here}}
  145. blockA = ^{ }; // expected-error {{cannot assign to variable 'blockA' with const-qualified type 'void (^const)(void)}}
  146. }
  147. // rdar://7072507
  148. int test19() {
  149. goto L0; // expected-error {{cannot jump}}
  150. __block int x; // expected-note {{jump bypasses setup of __block variable}}
  151. L0:
  152. x = 0;
  153. ^(){ ++x; }();
  154. return x;
  155. }
  156. // radr://7438948
  157. void test20() {
  158. int n = 7;
  159. int vla[n]; // expected-note {{declared here}}
  160. int (*vm)[n] = 0; // expected-note {{declared here}}
  161. vla[1] = 4341;
  162. ^{
  163. (void)vla[1]; // expected-error {{cannot refer to declaration with a variably modified type inside block}}
  164. (void)(vm+1); // expected-error {{cannot refer to declaration with a variably modified type inside block}}
  165. }();
  166. }
  167. // radr://7438948
  168. void test21() {
  169. int a[7]; // expected-note {{declared here}}
  170. __block int b[10]; // expected-note {{declared here}}
  171. a[1] = 1;
  172. ^{
  173. (void)a[1]; // expected-error {{cannot refer to declaration with an array type inside block}}
  174. (void)b[1]; // expected-error {{cannot refer to declaration with an array type inside block}}
  175. }();
  176. }
  177. // rdar ://8218839
  178. const char * (^func)(void) = ^{ return __func__; };
  179. const char * (^function)(void) = ^{ return __FUNCTION__; };
  180. const char * (^pretty)(void) = ^{ return __PRETTY_FUNCTION__; };