1*40ba1f60SPiJoules // RUN: %clang_cc1 -ffixed-point -fsyntax-only -verify -Wformat -isystem %S/Inputs %s
2*40ba1f60SPiJoules // RUN: %clang_cc1 -fsyntax-only -verify -Wformat -isystem %S/Inputs %s -DWITHOUT_FIXED_POINT
3*40ba1f60SPiJoules
4*40ba1f60SPiJoules int printf(const char *restrict, ...);
5*40ba1f60SPiJoules
6*40ba1f60SPiJoules short s;
7*40ba1f60SPiJoules unsigned short us;
8*40ba1f60SPiJoules int i;
9*40ba1f60SPiJoules unsigned int ui;
10*40ba1f60SPiJoules long l;
11*40ba1f60SPiJoules unsigned long ul;
12*40ba1f60SPiJoules float fl;
13*40ba1f60SPiJoules double d;
14*40ba1f60SPiJoules char c;
15*40ba1f60SPiJoules unsigned char uc;
16*40ba1f60SPiJoules
17*40ba1f60SPiJoules #ifndef WITHOUT_FIXED_POINT
18*40ba1f60SPiJoules short _Fract sf;
19*40ba1f60SPiJoules _Fract f;
20*40ba1f60SPiJoules long _Fract lf;
21*40ba1f60SPiJoules unsigned short _Fract usf;
22*40ba1f60SPiJoules unsigned _Fract uf;
23*40ba1f60SPiJoules unsigned long _Fract ulf;
24*40ba1f60SPiJoules short _Accum sa;
25*40ba1f60SPiJoules _Accum a;
26*40ba1f60SPiJoules long _Accum la;
27*40ba1f60SPiJoules unsigned short _Accum usa;
28*40ba1f60SPiJoules unsigned _Accum ua;
29*40ba1f60SPiJoules unsigned long _Accum ula;
30*40ba1f60SPiJoules _Sat short _Fract sat_sf;
31*40ba1f60SPiJoules _Sat _Fract sat_f;
32*40ba1f60SPiJoules _Sat long _Fract sat_lf;
33*40ba1f60SPiJoules _Sat unsigned short _Fract sat_usf;
34*40ba1f60SPiJoules _Sat unsigned _Fract sat_uf;
35*40ba1f60SPiJoules _Sat unsigned long _Fract sat_ulf;
36*40ba1f60SPiJoules _Sat short _Accum sat_sa;
37*40ba1f60SPiJoules _Sat _Accum sat_a;
38*40ba1f60SPiJoules _Sat long _Accum sat_la;
39*40ba1f60SPiJoules _Sat unsigned short _Accum sat_usa;
40*40ba1f60SPiJoules _Sat unsigned _Accum sat_ua;
41*40ba1f60SPiJoules _Sat unsigned long _Accum sat_ula;
42*40ba1f60SPiJoules
test_invalid_args(void)43*40ba1f60SPiJoules void test_invalid_args(void) {
44*40ba1f60SPiJoules /// None of these should match against a fixed point type.
45*40ba1f60SPiJoules printf("%r", s); // expected-warning{{format specifies type '_Fract' but the argument has type 'short'}}
46*40ba1f60SPiJoules printf("%r", us); // expected-warning{{format specifies type '_Fract' but the argument has type 'unsigned short'}}
47*40ba1f60SPiJoules printf("%r", i); // expected-warning{{format specifies type '_Fract' but the argument has type 'int'}}
48*40ba1f60SPiJoules printf("%r", ui); // expected-warning{{format specifies type '_Fract' but the argument has type 'unsigned int'}}
49*40ba1f60SPiJoules printf("%r", l); // expected-warning{{format specifies type '_Fract' but the argument has type 'long'}}
50*40ba1f60SPiJoules printf("%r", ul); // expected-warning{{format specifies type '_Fract' but the argument has type 'unsigned long'}}
51*40ba1f60SPiJoules printf("%r", fl); // expected-warning{{format specifies type '_Fract' but the argument has type 'float'}}
52*40ba1f60SPiJoules printf("%r", d); // expected-warning{{format specifies type '_Fract' but the argument has type 'double'}}
53*40ba1f60SPiJoules printf("%r", c); // expected-warning{{format specifies type '_Fract' but the argument has type 'char'}}
54*40ba1f60SPiJoules printf("%r", uc); // expected-warning{{format specifies type '_Fract' but the argument has type 'unsigned char'}}
55*40ba1f60SPiJoules }
56*40ba1f60SPiJoules
test_fixed_point_specifiers(void)57*40ba1f60SPiJoules void test_fixed_point_specifiers(void) {
58*40ba1f60SPiJoules printf("%r", f);
59*40ba1f60SPiJoules printf("%R", uf);
60*40ba1f60SPiJoules printf("%k", a);
61*40ba1f60SPiJoules printf("%K", ua);
62*40ba1f60SPiJoules
63*40ba1f60SPiJoules /// Test different sizes.
64*40ba1f60SPiJoules printf("%r", sf); // expected-warning{{format specifies type '_Fract' but the argument has type 'short _Fract'}}
65*40ba1f60SPiJoules printf("%r", lf); // expected-warning{{format specifies type '_Fract' but the argument has type 'long _Fract'}}
66*40ba1f60SPiJoules printf("%R", usf); // expected-warning{{format specifies type 'unsigned _Fract' but the argument has type 'unsigned short _Fract'}}
67*40ba1f60SPiJoules printf("%R", ulf); // expected-warning{{format specifies type 'unsigned _Fract' but the argument has type 'unsigned long _Fract'}}
68*40ba1f60SPiJoules printf("%k", sa); // expected-warning{{format specifies type '_Accum' but the argument has type 'short _Accum'}}
69*40ba1f60SPiJoules printf("%k", la); // expected-warning{{format specifies type '_Accum' but the argument has type 'long _Accum'}}
70*40ba1f60SPiJoules printf("%K", usa); // expected-warning{{format specifies type 'unsigned _Accum' but the argument has type 'unsigned short _Accum'}}
71*40ba1f60SPiJoules printf("%K", ula); // expected-warning{{format specifies type 'unsigned _Accum' but the argument has type 'unsigned long _Accum'}}
72*40ba1f60SPiJoules
73*40ba1f60SPiJoules /// Test signs.
74*40ba1f60SPiJoules printf("%r", uf); // expected-warning{{format specifies type '_Fract' but the argument has type 'unsigned _Fract'}}
75*40ba1f60SPiJoules printf("%R", f); // expected-warning{{format specifies type 'unsigned _Fract' but the argument has type '_Fract'}}
76*40ba1f60SPiJoules printf("%k", ua); // expected-warning{{format specifies type '_Accum' but the argument has type 'unsigned _Accum'}}
77*40ba1f60SPiJoules printf("%K", a); // expected-warning{{format specifies type 'unsigned _Accum' but the argument has type '_Accum'}}
78*40ba1f60SPiJoules
79*40ba1f60SPiJoules /// Test between types.
80*40ba1f60SPiJoules printf("%r", a); // expected-warning{{format specifies type '_Fract' but the argument has type '_Accum'}}
81*40ba1f60SPiJoules printf("%R", ua); // expected-warning{{format specifies type 'unsigned _Fract' but the argument has type 'unsigned _Accum'}}
82*40ba1f60SPiJoules printf("%k", f); // expected-warning{{format specifies type '_Accum' but the argument has type '_Fract'}}
83*40ba1f60SPiJoules printf("%K", uf); // expected-warning{{format specifies type 'unsigned _Accum' but the argument has type 'unsigned _Fract'}}
84*40ba1f60SPiJoules
85*40ba1f60SPiJoules /// Test saturated types.
86*40ba1f60SPiJoules printf("%r", sat_f);
87*40ba1f60SPiJoules printf("%R", sat_uf);
88*40ba1f60SPiJoules printf("%k", sat_a);
89*40ba1f60SPiJoules printf("%K", sat_ua);
90*40ba1f60SPiJoules }
91*40ba1f60SPiJoules
test_length_modifiers_and_flags(void)92*40ba1f60SPiJoules void test_length_modifiers_and_flags(void) {
93*40ba1f60SPiJoules printf("%hr", sf);
94*40ba1f60SPiJoules printf("%lr", lf);
95*40ba1f60SPiJoules printf("%hR", usf);
96*40ba1f60SPiJoules printf("%lR", ulf);
97*40ba1f60SPiJoules printf("%hk", sa);
98*40ba1f60SPiJoules printf("%lk", la);
99*40ba1f60SPiJoules printf("%hK", usa);
100*40ba1f60SPiJoules printf("%lK", ula);
101*40ba1f60SPiJoules
102*40ba1f60SPiJoules printf("%hr", sat_sf);
103*40ba1f60SPiJoules printf("%lr", sat_lf);
104*40ba1f60SPiJoules printf("%hR", sat_usf);
105*40ba1f60SPiJoules printf("%lR", sat_ulf);
106*40ba1f60SPiJoules printf("%hk", sat_sa);
107*40ba1f60SPiJoules printf("%lk", sat_la);
108*40ba1f60SPiJoules printf("%hK", sat_usa);
109*40ba1f60SPiJoules printf("%lK", sat_ula);
110*40ba1f60SPiJoules
111*40ba1f60SPiJoules printf("%10r", f);
112*40ba1f60SPiJoules printf("%10.10r", f);
113*40ba1f60SPiJoules printf("%010r", f);
114*40ba1f60SPiJoules printf("%-10r", f);
115*40ba1f60SPiJoules printf("%.10r", f);
116*40ba1f60SPiJoules printf("%+r", f);
117*40ba1f60SPiJoules printf("% r", f);
118*40ba1f60SPiJoules printf("%#r", f);
119*40ba1f60SPiJoules printf("%#.r", f);
120*40ba1f60SPiJoules printf("%#.0r", f);
121*40ba1f60SPiJoules
122*40ba1f60SPiJoules /// Test some invalid length modifiers.
123*40ba1f60SPiJoules printf("%zr", f); // expected-warning{{length modifier 'z' results in undefined behavior or no effect with 'r' conversion specifier}}
124*40ba1f60SPiJoules printf("%llr", f); // expected-warning{{length modifier 'll' results in undefined behavior or no effect with 'r' conversion specifier}}
125*40ba1f60SPiJoules printf("%hhr", f); // expected-warning{{length modifier 'hh' results in undefined behavior or no effect with 'r' conversion specifier}}
126*40ba1f60SPiJoules
127*40ba1f60SPiJoules // + on an unsigned fixed point type.
128*40ba1f60SPiJoules printf("%+hR", usf); // expected-warning{{flag '+' results in undefined behavior with 'R' conversion specifier}}
129*40ba1f60SPiJoules printf("%+R", uf); // expected-warning{{flag '+' results in undefined behavior with 'R' conversion specifier}}
130*40ba1f60SPiJoules printf("%+lR", ulf); // expected-warning{{flag '+' results in undefined behavior with 'R' conversion specifier}}
131*40ba1f60SPiJoules printf("%+hK", usa); // expected-warning{{flag '+' results in undefined behavior with 'K' conversion specifier}}
132*40ba1f60SPiJoules printf("%+K", ua); // expected-warning{{flag '+' results in undefined behavior with 'K' conversion specifier}}
133*40ba1f60SPiJoules printf("%+lK", ula); // expected-warning{{flag '+' results in undefined behavior with 'K' conversion specifier}}
134*40ba1f60SPiJoules printf("% hR", usf); // expected-warning{{flag ' ' results in undefined behavior with 'R' conversion specifier}}
135*40ba1f60SPiJoules printf("% R", uf); // expected-warning{{flag ' ' results in undefined behavior with 'R' conversion specifier}}
136*40ba1f60SPiJoules printf("% lR", ulf); // expected-warning{{flag ' ' results in undefined behavior with 'R' conversion specifier}}
137*40ba1f60SPiJoules printf("% hK", usa); // expected-warning{{flag ' ' results in undefined behavior with 'K' conversion specifier}}
138*40ba1f60SPiJoules printf("% K", ua); // expected-warning{{flag ' ' results in undefined behavior with 'K' conversion specifier}}
139*40ba1f60SPiJoules printf("% lK", ula); // expected-warning{{flag ' ' results in undefined behavior with 'K' conversion specifier}}
140*40ba1f60SPiJoules }
141*40ba1f60SPiJoules #else
test_fixed_point_specifiers_no_printf()142*40ba1f60SPiJoules void test_fixed_point_specifiers_no_printf() {
143*40ba1f60SPiJoules printf("%k", i); // expected-warning{{invalid conversion specifier 'k'}}
144*40ba1f60SPiJoules printf("%K", i); // expected-warning{{invalid conversion specifier 'K'}}
145*40ba1f60SPiJoules printf("%r", i); // expected-warning{{invalid conversion specifier 'r'}}
146*40ba1f60SPiJoules printf("%R", i); // expected-warning{{invalid conversion specifier 'R'}}
147*40ba1f60SPiJoules }
148*40ba1f60SPiJoules #endif // WITHOUT_FIXED_POINT
149