1 /* { dg-do compile } */
2 /* { dg-options "-O2 -Wformat -Wformat-truncation=2 -ftrack-macro-expansion=0" } */
3
4 typedef struct
5 {
6 char a0[0];
7 /* Separate a0 from a1 to prevent the former from being substituted
8 for the latter and causing false positives. */
9 int: 8;
10 char a1[1];
11 char a2[2];
12 char a3[3];
13 char a4[4];
14 char ax[];
15 } Arrays;
16
17 char buffer[1024];
18 #define buffer(size) (buffer + sizeof buffer - size)
19
value_range(int min,int max)20 static int value_range (int min, int max)
21 {
22 extern int value (void);
23 int val = value ();
24 return val < min || max < val ? min : val;
25 }
26
27 #define R(min, max) value_range (min, max)
28
29 /* Verify that calls to snprintf whose return value is unused are
30 diagnosed if certain or possible truncation is detected. */
31
32 #define T(size, ...) \
33 __builtin_snprintf (buffer (size), size, __VA_ARGS__)
34
test_int_retval_unused(void)35 void test_int_retval_unused (void)
36 {
37 T (2, "%i", 123); /* { dg-warning "output truncated" } */
38 T (2, "%i", R (1, 99)); /* { dg-warning "output may be truncated" } */
39 T (2, "%i", R (10, 99)); /* { dg-warning "output truncated" } */
40 T (3, "%i%i", R (1, 99), R (1, 99)); /* { dg-warning "output may be truncated" } */
41 }
42
test_string_retval_unused(const Arrays * ar)43 void test_string_retval_unused (const Arrays *ar)
44 {
45 /* At level 2 strings of unknown length are assumed to be 1 character
46 long, so the following is diagnosed. */
47 T (1, "%-s", ar->a0); /* { dg-warning "output may be truncated" } */
48 T (1, "%-s", ar->a1);
49 T (1, "%-s", ar->a2); /* { dg-warning "output may be truncated" } */
50 }
51
52
53 /* Verify that (at -Wformat-trunc=2) calls to snprintf whose return value
54 is used are diagnosed the same way as those whose value is unused. */
55
56 volatile int retval;
57
58 #undef T
59 #define T(size, ...) \
60 retval = __builtin_snprintf (buffer (size), size, __VA_ARGS__)
61
test_int_retval_used(void)62 void test_int_retval_used (void)
63 {
64 T (2, "%i", 123); /* { dg-warning "output truncated" } */
65 T (2, "%i", R (1, 99)); /* { dg-warning "output may be truncated" } */
66 T (2, "%i", R (10, 99)); /* { dg-warning "output truncated" } */
67 T (3, "%i%i", R (1, 99), R (1, 99)); /* { dg-warning "output may be truncated" } */
68 }
69
test_string_retval_used(const Arrays * ar)70 void test_string_retval_used (const Arrays *ar)
71 {
72 T (1, "%-s", ar->a0); /* { dg-warning "output may be truncated" } */
73 T (1, "%-s", ar->a1);
74 T (1, "%-s", ar->a2); /* { dg-warning "output may be truncated" } */
75 }
76