1 /* PR tree-optimization/80523 - -Wformat-overflow doesn't consider
2    -fexec-charset
3    { dg-do compile }
4    { dg-require-iconv "IBM1047" }
5    { dg-options "-O2 -Wall -Wno-format -Wformat-overflow -fexec-charset=IBM1047 -ftrack-macro-expansion=0" } */
6 
7 char buf[1];
8 void sink (void*);
9 
10 #define T(...) (__builtin_sprintf (buf + 1, __VA_ARGS__), sink (buf))
11 
12 /* Exercise all special C and POSIX characters.  */
13 
test_characters()14 void test_characters ()
15 {
16   T ("%%");           /* { dg-warning ".%%. directive writing 1 byte" } */
17 
18   T ("%A",    0.0);   /* { dg-warning ".%A. directive writing between 6 and 20 " } */
19   T ("%a",    0.0);   /* { dg-warning ".%a. directive writing between 6 and 20 " } */
20 
21   T ("%C",    'a');   /* { dg-warning ".%C. directive writing 1 byte" "bug 80537" { xfail *-*-* } } */
22   T ("%c",    'a');   /* { dg-warning ".%c. directive writing 1 byte" } */
23 
24   T ("%d",     12);   /* { dg-warning ".%d. directive writing 2 bytes" } */
25   T ("% d",    12);   /* { dg-warning ".% d. directive writing 3 bytes" } */
26   T ("%-d",   123);   /* { dg-warning ".%-d. directive writing 3 bytes" } */
27   T ("%+d",  1234);   /* { dg-warning ".%\\+d. directive writing 5 bytes" } */
28   T ("%'d",  1234);   /* { dg-warning ".%'d. directive writing 5 bytes" "bug 80535" { xfail *-*-* } } */
29   T ("%1$d", 2345);   /* { dg-warning ".%1\\\$d. directive writing 4 bytes" } */
30 
31   /* Verify that digits are correctly interpreted as width and precision.  */
32   T ("%0d", 12345);   /* { dg-warning ".%0d. directive writing 5 bytes" } */
33   T ("%1d", 12345);   /* { dg-warning ".%1d. directive writing 5 bytes" } */
34   T ("%2d", 12345);   /* { dg-warning ".%2d. directive writing 5 bytes" } */
35   T ("%3d", 12345);   /* { dg-warning ".%3d. directive writing 5 bytes" } */
36   T ("%4d", 12345);   /* { dg-warning ".%4d. directive writing 5 bytes" } */
37   T ("%5d", 12345);   /* { dg-warning ".%5d. directive writing 5 bytes" } */
38   T ("%6d", 12345);   /* { dg-warning ".%6d. directive writing 6 bytes" } */
39   T ("%7d", 12345);   /* { dg-warning ".%7d. directive writing 7 bytes" } */
40   T ("%8d", 12345);   /* { dg-warning ".%8d. directive writing 8 bytes" } */
41   T ("%9d", 12345);   /* { dg-warning ".%9d. directive writing 9 bytes" } */
42 
43   T ("%.0d", 12345);  /* { dg-warning ".%.0d. directive writing 5 bytes" } */
44   T ("%.1d", 12345);  /* { dg-warning ".%.1d. directive writing 5 bytes" } */
45   T ("%.2d", 12345);  /* { dg-warning ".%.2d. directive writing 5 bytes" } */
46   T ("%.3d", 12345);  /* { dg-warning ".%.3d. directive writing 5 bytes" } */
47   T ("%.4d", 12345);  /* { dg-warning ".%.4d. directive writing 5 bytes" } */
48   T ("%.5d", 12345);  /* { dg-warning ".%.5d. directive writing 5 bytes" } */
49   T ("%.6d", 12345);  /* { dg-warning ".%.6d. directive writing 6 bytes" } */
50   T ("%.7d", 12345);  /* { dg-warning ".%.7d. directive writing 7 bytes" } */
51   T ("%.8d", 12345);  /* { dg-warning ".%.8d. directive writing 8 bytes" } */
52   T ("%.9d", 12345);  /* { dg-warning ".%.9d. directive writing 9 bytes" } */
53 
54   T ("%hhd",    12);   /* { dg-warning ".%hhd. directive writing 2 bytes" } */
55   T ("%hd",    234);   /* { dg-warning ".%hd. directive writing 3 bytes" } */
56 
57   {
58     const __PTRDIFF_TYPE__ i = 3456;
59     T ("%jd",   i);  /* { dg-warning ".%jd. directive writing 4 bytes" } */
60   }
61 
62   T ("%ld",  45678L);  /* { dg-warning ".%ld. directive writing 5 bytes" } */
63 
64   {
65     const __PTRDIFF_TYPE__ i = 56789;
66     T ("%td",   i);  /* { dg-warning ".%td. directive writing 5 bytes" } */
67   }
68 
69   {
70     const __SIZE_TYPE__ i = 67890;
71     T ("%zd",   i);  /* { dg-warning ".%zd. directive writing 5 bytes" } */
72   }
73 
74   T ("%E",    0.0);   /* { dg-warning ".%E. directive writing 12 bytes" } */
75   T ("%e",    0.0);   /* { dg-warning ".%e. directive writing 12 bytes" } */
76   T ("%F",    0.0);   /* { dg-warning ".%F. directive writing 8 bytes" } */
77   T ("%f",    0.0);   /* { dg-warning ".%f. directive writing 8 bytes" } */
78   T ("%G",    0.0);   /* { dg-warning ".%G. directive writing 1 byte" } */
79   T ("%g",    0.0);   /* { dg-warning ".%g. directive writing 1 byte" } */
80 
81   T ("%i",     123);  /* { dg-warning ".%i. directive writing 3 bytes" } */
82 
83   {
84     int n;
85 
86     T ("%n",    &n);  /* { dg-warning "writing a terminating nul" } */
87     T ("%nH",   &n);  /* { dg-warning ".H. directive writing 1 byte" } */
88   }
89 
90   T ("%o",     999);  /* { dg-warning ".%o. directive writing 4 bytes" } */
91   T ("%#o",    999);  /* { dg-warning ".%#o. directive writing 5 bytes" } */
92 
93   T ("%x",    1234);  /* { dg-warning ".%x. directive writing 3 bytes" } */
94   T ("%#X",   1235);  /* { dg-warning ".%#X. directive writing 5 bytes" } */
95 
96   T ("%S",    L"1");  /* { dg-warning ".%S. directive writing 1 byte" } */
97   T ("%-s",    "1");  /* { dg-warning ".%-s. directive writing 1 byte" } */
98 
99   /* Verify that characters in the source character set appear in
100      the text of the warning unchanged (i.e., not as their equivalents
101      in the execution character set on the target).  The trailing %%
102      disables sprintf->strcpy optimization.  */
103   T ("ABCDEFGHIJ%%");   /* { dg-warning ".ABCDEFGHIJ. directive writing 10 bytes" } */
104   T ("KLMNOPQRST%%");   /* { dg-warning ".KLMNOPQRST. directive writing 10 bytes" } */
105   T ("UVWXYZ%%");       /* { dg-warning ".UVWXYZ. directive writing 6 bytes" } */
106 
107   T ("abcdefghij%%");   /* { dg-warning ".abcdefghij. directive writing 10 bytes" } */
108   T ("klmnopqrst%%");   /* { dg-warning ".klmnopqrst. directive writing 10 bytes" } */
109   T ("uvwxyz%%");       /* { dg-warning ".uvwxyz. directive writing 6 bytes" } */
110 }
111 
112 #undef T
113 #define T(...) (__builtin_sprintf (d, __VA_ARGS__), sink (d))
114 
test_width_and_precision_out_of_range(char * d)115 void test_width_and_precision_out_of_range (char *d)
116 {
117   /* The range here happens to be a property of the compiler, not
118      one of the target.  */
119   T ("%9223372036854775808i", 0);    /* { dg-warning "width out of range" } */
120   /* { dg-warning "result to exceed .INT_MAX." "" { target *-*-* } .-1 } */
121   T ("%.9223372036854775808i", 0);   /* { dg-warning "precision out of range" } */
122   /* { dg-warning "causes result to exceed .INT_MAX." "" { target *-*-* } .-1 } */
123 
124   /* The following is diagnosed by -Wformat (disabled here).  */
125   /* T ("%9223372036854775808$i", 0); */
126 }
127 
128 /* Verify that an excessively long directive is truncated and the truncation
129    is indicated by three trailing dots in the text of the warning.  */
130 
test_overlong_plain_string()131 void test_overlong_plain_string ()
132 {
133   static const char longfmtstr[] =
134     "0123456789012345678901234567890123456789012345678901234567890123456789%%";
135 
136   char d[1];
137   T (longfmtstr);   /* { dg-warning ".0123\[0-9\]\*\.\.\.. directive writing 70 bytes" } */
138 }
139