xref: /llvm-project/clang/test/Sema/format-fixed-point.c (revision 40ba1f60e9f4b186d71272d4bc23b5af6204244d)
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