1 #include <array_length.h>
2 #include <float.h>
3 #include <math.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <wchar.h>
7 #include <libc-diag.h>
8 
9 static int
t1(void)10 t1 (void)
11 {
12   int n = -1;
13   sscanf ("abc  ", "abc %n", &n);
14   printf ("t1: count=%d\n", n);
15 
16   return n != 5;
17 }
18 
19 static int
t2(void)20 t2 (void)
21 {
22   int result = 0;
23   int n;
24   long N;
25   int retval;
26 #define SCAN(INPUT, FORMAT, VAR, EXP_RES, EXP_VAL) \
27   VAR = -1; \
28   retval = sscanf (INPUT, FORMAT, &VAR); \
29   printf ("sscanf (\"%s\", \"%s\", &x) => %d, x = %ld\n", \
30 	  INPUT, FORMAT, retval, (long int) VAR); \
31   result |= retval != EXP_RES || VAR != EXP_VAL
32 
33   /* This function is testing corner cases of the scanf format string,
34      so they do not all conform to -Wformat's expectations.  */
35   DIAG_PUSH_NEEDS_COMMENT;
36   DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat");
37   DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat-extra-args");
38 
39   SCAN ("12345", "%ld", N, 1, 12345);
40   SCAN ("12345", "%llllld", N, 0, -1);
41   SCAN ("12345", "%LLLLLd", N, 0, -1);
42   SCAN ("test ", "%*s%n",  n, 0, 4);
43   SCAN ("test ", "%2*s%n",  n, 0, -1);
44   SCAN ("12 ",   "%l2d",  n, 0, -1);
45   SCAN ("12 ",   "%2ld",  N, 1, 12);
46 
47   n = -1;
48   N = -1;
49   retval = sscanf ("1 1", "%d %Z", &n, &N);
50   printf ("sscanf (\"1 1\", \"%%d %%Z\", &n, &N) => %d, n = %d, N = %ld\n", \
51 	  retval, n, N); \
52   result |= retval != 1 || n != 1 || N != -1;
53 
54   DIAG_POP_NEEDS_COMMENT;
55 
56   return result;
57 }
58 
59 static int
t3(void)60 t3 (void)
61 {
62   char buf[80];
63   wchar_t wbuf[80];
64   int result = 0;
65   int retval;
66 
67   retval = sprintf (buf, "%p", (char *) NULL);
68   result |= retval != 5 || strcmp (buf, "(nil)") != 0;
69 
70   retval = swprintf (wbuf, array_length (wbuf), L"%p", (char *) NULL);
71   result |= retval != 5 || wcscmp (wbuf, L"(nil)") != 0;
72 
73   return result;
74 }
75 
76 volatile double qnanval;
77 volatile long double lqnanval;
78 /* A sNaN is only guaranteed to be representable in variables with static (or
79    thread-local) storage duration.  */
80 static volatile double snanval = __builtin_nans ("");
81 static volatile double msnanval = -__builtin_nans ("");
82 static volatile long double lsnanval = __builtin_nansl ("");
83 static volatile long double lmsnanval = -__builtin_nansl ("");
84 volatile double infval;
85 volatile long double linfval;
86 
87 
88 static int
F(void)89 F (void)
90 {
91   char buf[80];
92   wchar_t wbuf[40];
93   int result = 0;
94 
95   qnanval = NAN;
96 
97   /* The %f and %F arguments are in fact constants, but GCC is
98      prevented from seeing this (volatile is used) so it cannot tell
99      that the output is not truncated.  */
100   DIAG_PUSH_NEEDS_COMMENT;
101 #if __GNUC_PREREQ (7, 0)
102   DIAG_IGNORE_NEEDS_COMMENT (7.0, "-Wformat-truncation");
103 #endif
104 
105   snprintf (buf, sizeof buf, "%a %A %e %E %f %F %g %G",
106 	    qnanval, qnanval, qnanval, qnanval,
107 	    qnanval, qnanval, qnanval, qnanval);
108   result |= strcmp (buf, "nan NAN nan NAN nan NAN nan NAN") != 0;
109   printf ("expected \"nan NAN nan NAN nan NAN nan NAN\", got \"%s\"\n", buf);
110 
111   snprintf (buf, sizeof buf, "%a %A %e %E %f %F %g %G",
112 	    -qnanval, -qnanval, -qnanval, -qnanval,
113 	    -qnanval, -qnanval, -qnanval, -qnanval);
114   result |= strcmp (buf, "-nan -NAN -nan -NAN -nan -NAN -nan -NAN") != 0;
115   printf ("expected \"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got \"%s\"\n",
116 	  buf);
117 
118   snprintf (buf, sizeof buf, "%a %A %e %E %f %F %g %G",
119 	    snanval, snanval, snanval, snanval,
120 	    snanval, snanval, snanval, snanval);
121   result |= strcmp (buf, "nan NAN nan NAN nan NAN nan NAN") != 0;
122   printf ("expected \"nan NAN nan NAN nan NAN nan NAN\", got \"%s\"\n", buf);
123 
124   snprintf (buf, sizeof buf, "%a %A %e %E %f %F %g %G",
125 	    msnanval, msnanval, msnanval, msnanval,
126 	    msnanval, msnanval, msnanval, msnanval);
127   result |= strcmp (buf, "-nan -NAN -nan -NAN -nan -NAN -nan -NAN") != 0;
128   printf ("expected \"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got \"%s\"\n",
129 	  buf);
130 
131   infval = DBL_MAX * DBL_MAX;
132 
133   snprintf (buf, sizeof buf, "%a %A %e %E %f %F %g %G",
134 	    infval, infval, infval, infval, infval, infval, infval, infval);
135   result |= strcmp (buf, "inf INF inf INF inf INF inf INF") != 0;
136   printf ("expected \"inf INF inf INF inf INF inf INF\", got \"%s\"\n", buf);
137 
138   snprintf (buf, sizeof buf, "%a %A %e %E %f %F %g %G",
139 	    -infval, -infval, -infval, -infval,
140 	    -infval, -infval, -infval, -infval);
141   result |= strcmp (buf, "-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
142   printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
143 	  buf);
144 
145   swprintf (wbuf, array_length (wbuf), L"%a %A %e %E %f %F %g %G",
146 	    qnanval, qnanval, qnanval, qnanval,
147 	    qnanval, qnanval, qnanval, qnanval);
148   result |= wcscmp (wbuf, L"nan NAN nan NAN nan NAN nan NAN") != 0;
149   printf ("expected L\"nan NAN nan NAN nan NAN nan NAN\", got L\"%S\"\n", wbuf);
150 
151   swprintf (wbuf, array_length (wbuf), L"%a %A %e %E %f %F %g %G",
152 	    -qnanval, -qnanval, -qnanval, -qnanval,
153 	    -qnanval, -qnanval, -qnanval, -qnanval);
154   result |= wcscmp (wbuf, L"-nan -NAN -nan -NAN -nan -NAN -nan -NAN") != 0;
155   printf ("expected L\"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got L\"%S\"\n",
156 	  wbuf);
157 
158   swprintf (wbuf, array_length (wbuf), L"%a %A %e %E %f %F %g %G",
159 	    snanval, snanval, snanval, snanval,
160 	    snanval, snanval, snanval, snanval);
161   result |= wcscmp (wbuf, L"nan NAN nan NAN nan NAN nan NAN") != 0;
162   printf ("expected L\"nan NAN nan NAN nan NAN nan NAN\", got L\"%S\"\n", wbuf);
163 
164   swprintf (wbuf, array_length (wbuf), L"%a %A %e %E %f %F %g %G",
165 	    msnanval, msnanval, msnanval, msnanval,
166 	    msnanval, msnanval, msnanval, msnanval);
167   result |= wcscmp (wbuf, L"-nan -NAN -nan -NAN -nan -NAN -nan -NAN") != 0;
168   printf ("expected L\"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got L\"%S\"\n",
169 	  wbuf);
170 
171   swprintf (wbuf, array_length (wbuf), L"%a %A %e %E %f %F %g %G",
172 	    infval, infval, infval, infval, infval, infval, infval, infval);
173   result |= wcscmp (wbuf, L"inf INF inf INF inf INF inf INF") != 0;
174   printf ("expected L\"inf INF inf INF inf INF inf INF\", got L\"%S\"\n", wbuf);
175 
176   swprintf (wbuf, array_length (wbuf), L"%a %A %e %E %f %F %g %G",
177 	    -infval, -infval, -infval, -infval,
178 	    -infval, -infval, -infval, -infval);
179   result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
180   printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
181 	  wbuf);
182 
183   lqnanval = NAN;
184 
185   snprintf (buf, sizeof buf, "%La %LA %Le %LE %Lf %LF %Lg %LG",
186 	    lqnanval, lqnanval, lqnanval, lqnanval,
187 	    lqnanval, lqnanval, lqnanval, lqnanval);
188   result |= strcmp (buf, "nan NAN nan NAN nan NAN nan NAN") != 0;
189   printf ("expected \"nan NAN nan NAN nan NAN nan NAN\", got \"%s\"\n", buf);
190 
191   snprintf (buf, sizeof buf, "%La %LA %Le %LE %Lf %LF %Lg %LG",
192 	    -lqnanval, -lqnanval, -lqnanval, -lqnanval,
193 	    -lqnanval, -lqnanval, -lqnanval, -lqnanval);
194   result |= strcmp (buf, "-nan -NAN -nan -NAN -nan -NAN -nan -NAN") != 0;
195   printf ("expected \"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got \"%s\"\n",
196 	  buf);
197 
198   snprintf (buf, sizeof buf, "%La %LA %Le %LE %Lf %LF %Lg %LG",
199 	    lsnanval, lsnanval, lsnanval, lsnanval,
200 	    lsnanval, lsnanval, lsnanval, lsnanval);
201   result |= strcmp (buf, "nan NAN nan NAN nan NAN nan NAN") != 0;
202   printf ("expected \"nan NAN nan NAN nan NAN nan NAN\", got \"%s\"\n", buf);
203 
204   snprintf (buf, sizeof buf, "%La %LA %Le %LE %Lf %LF %Lg %LG",
205 	    lmsnanval, lmsnanval, lmsnanval, lmsnanval,
206 	    lmsnanval, lmsnanval, lmsnanval, lmsnanval);
207   result |= strcmp (buf, "-nan -NAN -nan -NAN -nan -NAN -nan -NAN") != 0;
208   printf ("expected \"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got \"%s\"\n",
209 	  buf);
210 
211   linfval = LDBL_MAX * LDBL_MAX;
212 
213   snprintf (buf, sizeof buf, "%La %LA %Le %LE %Lf %LF %Lg %LG",
214 	    linfval, linfval, linfval, linfval,
215 	    linfval, linfval, linfval, linfval);
216   result |= strcmp (buf, "inf INF inf INF inf INF inf INF") != 0;
217   printf ("expected \"inf INF inf INF inf INF inf INF\", got \"%s\"\n", buf);
218 
219   snprintf (buf, sizeof buf, "%La %LA %Le %LE %Lf %LF %Lg %LG",
220 	    -linfval, -linfval, -linfval, -linfval,
221 	    -linfval, -linfval, -linfval, -linfval);
222   result |= strcmp (buf, "-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
223   printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
224 	  buf);
225 
226   swprintf (wbuf, array_length (wbuf),
227 	    L"%La %LA %Le %LE %Lf %LF %Lg %LG",
228 	    lqnanval, lqnanval, lqnanval, lqnanval,
229 	    lqnanval, lqnanval, lqnanval, lqnanval);
230   result |= wcscmp (wbuf, L"nan NAN nan NAN nan NAN nan NAN") != 0;
231   printf ("expected L\"nan NAN nan NAN nan NAN nan NAN\", got L\"%S\"\n", wbuf);
232 
233   swprintf (wbuf, array_length (wbuf),
234 	    L"%La %LA %Le %LE %Lf %LF %Lg %LG",
235 	    -lqnanval, -lqnanval, -lqnanval, -lqnanval,
236 	    -lqnanval, -lqnanval, -lqnanval, -lqnanval);
237   result |= wcscmp (wbuf, L"-nan -NAN -nan -NAN -nan -NAN -nan -NAN") != 0;
238   printf ("expected L\"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got L\"%S\"\n",
239 	  wbuf);
240 
241   swprintf (wbuf, array_length (wbuf),
242 	    L"%La %LA %Le %LE %Lf %LF %Lg %LG",
243 	    lsnanval, lsnanval, lsnanval, lsnanval,
244 	    lsnanval, lsnanval, lsnanval, lsnanval);
245   result |= wcscmp (wbuf, L"nan NAN nan NAN nan NAN nan NAN") != 0;
246   printf ("expected L\"nan NAN nan NAN nan NAN nan NAN\", got L\"%S\"\n", wbuf);
247 
248   swprintf (wbuf, array_length (wbuf),
249 	    L"%La %LA %Le %LE %Lf %LF %Lg %LG",
250 	    lmsnanval, lmsnanval, lmsnanval, lmsnanval,
251 	    lmsnanval, lmsnanval, lmsnanval, lmsnanval);
252   result |= wcscmp (wbuf, L"-nan -NAN -nan -NAN -nan -NAN -nan -NAN") != 0;
253   printf ("expected L\"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got L\"%S\"\n",
254 	  wbuf);
255 
256   swprintf (wbuf, array_length (wbuf),
257 	    L"%La %LA %Le %LE %Lf %LF %Lg %LG",
258 	    linfval, linfval, linfval, linfval,
259 	    linfval, linfval, linfval, linfval);
260   result |= wcscmp (wbuf, L"inf INF inf INF inf INF inf INF") != 0;
261   printf ("expected L\"inf INF inf INF inf INF inf INF\", got L\"%S\"\n", wbuf);
262 
263   swprintf (wbuf, array_length (wbuf),
264 	    L"%La %LA %Le %LE %Lf %LF %Lg %LG",
265 	    -linfval, -linfval, -linfval, -linfval,
266 	    -linfval, -linfval, -linfval, -linfval);
267   result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
268   printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
269 	  wbuf);
270 
271   DIAG_POP_NEEDS_COMMENT;
272 
273   return result;
274 }
275 
276 int
main(int argc,char * argv[])277 main (int argc, char *argv[])
278 {
279   int result = 0;
280 
281   result |= t1 ();
282   result |= t2 ();
283   result |= t3 ();
284   result |= F ();
285 
286   result |= fflush (stdout) == EOF;
287 
288   return result;
289 }
290