aboutsummaryrefslogtreecommitdiff
path: root/test/Sema/block-misc.c
blob: b2d4fd822900a65d61e24506cccec9e6dfd69dea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// RUN: clang-cc -fsyntax-only -verify %s -fblocks
void donotwarn();

int (^IFP) ();
int (^II) (int);
int test1() {
  int (^PFR) (int) = 0;	// OK
  PFR = II;	// OK

  if (PFR == II)	// OK
    donotwarn();

  if (PFR == IFP) // expected-error {{comparison of distinct block types}}
    donotwarn();

  if (PFR == (int (^) (int))IFP) // OK
    donotwarn();

  if (PFR == 0) // OK
    donotwarn();

  if (PFR)	// OK
    donotwarn();

  if (!PFR)	// OK
    donotwarn();

  return PFR != IFP;	// expected-error {{comparison of distinct block types}}
}

int test2(double (^S)()) {
  double (^I)(int)  = (void*) S;
  (void*)I = (void *)S; 	// expected-error {{assignment to cast is illegal, lvalue casts are not supported}}

  void *pv = I;

  pv = S;		

  I(1);

  return (void*)I == (void *)S;
}

int^ x; // expected-error {{block pointer to non-function type is invalid}}
int^^ x1; // expected-error {{block pointer to non-function type is invalid}} expected-error {{block pointer to non-function type is invalid}}

int test3() {
  char *^ y; // expected-error {{block pointer to non-function type is invalid}}
}



enum {NSBIRLazilyAllocated = 0};

int test4(int argc) {  // rdar://6251437
  ^{
    switch (argc) {
      case NSBIRLazilyAllocated:  // is an integer constant expression.
      default:
        break;
    }
  }();
  return 0;
}


// rdar://6257721 - reference to static/global is byref by default.
static int test5g;
void test5() {
  bar(^{ test5g = 1; });
}

// rdar://6405429 - __func__ in a block refers to the containing function name.
const char*test6() {
  return ^{
    return __func__;
  } ();
}

// radr://6732116 - block comparisons
void (^test7a)();
int test7(void (^p)()) {
  return test7a == p;
}


void test8() {
somelabel:
 // FIXME: This should say "jump out of block not legal" when gotos are allowed.
  ^{ goto somelabel; }();   // expected-error {{goto not allowed in block literal}}
}

void test9() {
  goto somelabel;       // expected-error {{use of undeclared label 'somelabel'}}
  ^{ somelabel: ; }();
}

void test10(int i) {
  switch (i) {
  case 41: ;
  ^{ case 42: ; }();     // expected-error {{'case' statement not in switch statement}}
  }
}

void test11(int i) {
  switch (i) {
  case 41: ;
    ^{ break; }();     // expected-error {{'break' statement not in loop or switch statement}}
  }
  
  for (; i < 100; ++i)
    ^{ break; }();     // expected-error {{'break' statement not in loop or switch statement}}
}