1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s
2*67e74705SXin Li
3*67e74705SXin Li #define NULL (void*)0
4*67e74705SXin Li
5*67e74705SXin Li #define ATTR __attribute__ ((__sentinel__))
6*67e74705SXin Li
7*67e74705SXin Li void foo1 (int x, ...) ATTR; // expected-note 3 {{function has been explicitly marked sentinel here}}
8*67e74705SXin Li void foo5 (int x, ...) __attribute__ ((__sentinel__(1))); // expected-note {{function has been explicitly marked sentinel here}}
9*67e74705SXin Li void foo6 (int x, ...) __attribute__ ((__sentinel__(5))); // expected-note {{function has been explicitly marked sentinel here}}
10*67e74705SXin Li void foo7 (int x, ...) __attribute__ ((__sentinel__(0))); // expected-note {{function has been explicitly marked sentinel here}}
11*67e74705SXin Li void foo10 (int x, ...) __attribute__ ((__sentinel__(1,1)));
12*67e74705SXin Li void foo12 (int x, ... ) ATTR; // expected-note {{function has been explicitly marked sentinel here}}
13*67e74705SXin Li
14*67e74705SXin Li #define FOOMACRO(...) foo1(__VA_ARGS__)
15*67e74705SXin Li
test1()16*67e74705SXin Li void test1() {
17*67e74705SXin Li foo1(1, NULL); // OK
18*67e74705SXin Li foo1(1, 0) ; // expected-warning {{missing sentinel in function call}}
19*67e74705SXin Li foo5(1, NULL, 2); // OK
20*67e74705SXin Li foo5(1,2,NULL, 1); // OK
21*67e74705SXin Li foo5(1, NULL, 2, 1); // expected-warning {{missing sentinel in function call}}
22*67e74705SXin Li
23*67e74705SXin Li foo6(1,2,3,4,5,6,7); // expected-warning {{missing sentinel in function call}}
24*67e74705SXin Li foo6(1,NULL,3,4,5,6,7); // OK
25*67e74705SXin Li foo7(1); // expected-warning {{not enough variable arguments in 'foo7' declaration to fit a sentinel}}
26*67e74705SXin Li foo7(1, NULL); // OK
27*67e74705SXin Li
28*67e74705SXin Li foo12(1); // expected-warning {{not enough variable arguments in 'foo12' declaration to fit a sentinel}}
29*67e74705SXin Li
30*67e74705SXin Li // PR 5685
31*67e74705SXin Li struct A {};
32*67e74705SXin Li struct A a, b, c;
33*67e74705SXin Li foo1(3, &a, &b, &c); // expected-warning {{missing sentinel in function call}}
34*67e74705SXin Li foo1(3, &a, &b, &c, (struct A*) 0);
35*67e74705SXin Li
36*67e74705SXin Li // PR11002
37*67e74705SXin Li FOOMACRO(1, 2); // expected-warning {{missing sentinel in function call}}
38*67e74705SXin Li }
39*67e74705SXin Li
40*67e74705SXin Li
41*67e74705SXin Li
42*67e74705SXin Li void (*e) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (1,1)));
43*67e74705SXin Li
test2()44*67e74705SXin Li void test2() {
45*67e74705SXin Li void (*b) (int arg, const char * format, ...) __attribute__ ((__sentinel__)); // expected-note {{function has been explicitly marked sentinel here}}
46*67e74705SXin Li void (*z) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (2))); // expected-note {{function has been explicitly marked sentinel here}}
47*67e74705SXin Li
48*67e74705SXin Li
49*67e74705SXin Li void (*y) (int arg, const char * format, ...) __attribute__ ((__sentinel__ (5))); // expected-note {{function has been explicitly marked sentinel here}}
50*67e74705SXin Li
51*67e74705SXin Li b(1, "%s", (void*)0); // OK
52*67e74705SXin Li b(1, "%s", 0); // expected-warning {{missing sentinel in function call}}
53*67e74705SXin Li z(1, "%s",4 ,1,0); // expected-warning {{missing sentinel in function call}}
54*67e74705SXin Li z(1, "%s", (void*)0, 1, 0); // OK
55*67e74705SXin Li
56*67e74705SXin Li y(1, "%s", 1,2,3,4,5,6,7); // expected-warning {{missing sentinel in function call}}
57*67e74705SXin Li
58*67e74705SXin Li y(1, "%s", (void*)0,3,4,5,6,7); // OK
59*67e74705SXin Li }
60