xref: /aosp_15_r20/external/clang/test/Sema/attr-sentinel.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
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