1// RUN: %clang_cc1 %s -verify -fsyntax-only
2
3void c1(int *a);
4
5extern int g1 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}}
6int g2 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}}
7static int g3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}}
8
9void t1()
10{
11    int v1 __attribute((cleanup)); // expected-error {{'cleanup' attribute takes one argument}}
12    int v2 __attribute((cleanup(1, 2))); // expected-error {{'cleanup' attribute takes one argument}}
13
14    static int v3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}}
15
16    int v4 __attribute((cleanup(h))); // expected-error {{use of undeclared identifier 'h'}}
17
18    int v5 __attribute((cleanup(c1)));
19    int v6 __attribute((cleanup(v3))); // expected-error {{'cleanup' argument 'v3' is not a function}}
20}
21
22struct s {
23    int a, b;
24};
25
26void c2();
27void c3(struct s a);
28
29void t2()
30{
31    int v1 __attribute__((cleanup(c2))); // expected-error {{'cleanup' function 'c2' must take 1 parameter}}
32    int v2 __attribute__((cleanup(c3))); // expected-error {{'cleanup' function 'c3' parameter has type 'struct s' which is incompatible with type 'int *'}}
33}
34
35// This is a manufactured testcase, but gcc accepts it...
36void c4(_Bool a);
37void t4() {
38  __attribute((cleanup(c4))) void* g;
39}
40
41void c5(void*) __attribute__((deprecated));  // expected-note{{'c5' has been explicitly marked deprecated here}}
42void t5() {
43  int i __attribute__((cleanup(c5)));  // expected-warning {{'c5' is deprecated}}
44}
45
46void t6(void) {
47  int i __attribute__((cleanup((void *)0)));  // expected-error {{'cleanup' argument is not a function}}
48}
49