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