1 /* PR middle-end/78786 - GCC hangs/out of memory calling sprintf with large
2    precision
3    { dg-do compile }
4    { dg-require-effective-target int32plus }
5    { dg-options "-Wformat-overflow -ftrack-macro-expansion=0" } */
6 
7 #define INT_MAX __INT_MAX__
8 #define INT_MIN (-INT_MAX - 1)
9 
10 typedef __SIZE_TYPE__ size_t;
11 
12 void sink (int, void*);
13 
14 char buf [1];
15 
16 #define T(n, fmt, ...)					\
17   sink (__builtin_sprintf (buf + sizeof buf - n, fmt, __VA_ARGS__), buf)
18 
test_integer_cst(void)19 void test_integer_cst (void)
20 {
21   T (0, "%*d",  INT_MIN, 0);     /* { dg-warning "writing 2147483648 bytes" } */
22   T (0, "%*d",  INT_MAX, 0);     /* { dg-warning "writing 2147483647 bytes" } */
23 
24   T (0, "%.*d", INT_MIN, 0);     /* { dg-warning "writing 1 byte" } */
25   T (0, "%.*d", INT_MAX, 0);     /* { dg-warning "writing 2147483647 bytes" } */
26 
27   T (0, "%*.*d", INT_MIN, INT_MIN, 0);   /* { dg-warning "writing 2147483648 bytes" } */
28 
29   T (0, "%*.*d", INT_MAX, INT_MAX, 0);   /* { dg-warning "writing 2147483647 bytes" } */
30 }
31 
test_integer_var(int i)32 void test_integer_var (int i)
33 {
34   T (0, "%*d",  INT_MIN, i);     /* { dg-warning "writing 2147483648 bytes" } */
35 
36   /* The following writes INT_MAX digits and, when i is negative, a minus
37      sign.  */
38   T (0, "%.*d", INT_MAX, i);     /* { dg-warning "writing between 2147483647 and 2147483648 bytes" } */
39 
40   T (0, "%.*d", INT_MIN, i);     /* { dg-warning "writing between 1 and 11 bytes" } */
41 
42   /* The following writes a range because of the possible minus sign.  */
43   T (0, "%.*d", INT_MAX, i);     /* { dg-warning "writing between 2147483647 and 2147483648 bytes" } */
44 
45   T (0, "%*.*d", INT_MIN, INT_MIN, i);   /* { dg-warning "writing 2147483648 bytes" } */
46 
47   /* The following writes INT_MAX digits and, when i is negative, a minus
48      sign.  */
49   T (0, "%*.*d", INT_MAX, INT_MAX, i);   /* { dg-warning "writing between 2147483647 and 2147483648 bytes" } */
50 }
51 
test_floating_a_cst(void)52 void test_floating_a_cst (void)
53 {
54   T (0, "%*a",  INT_MIN, 0.);     /* { dg-warning "writing 2147483648 bytes" } */
55   T (0, "%*a",  INT_MAX, 0.);     /* { dg-warning "writing 2147483647 bytes" } */
56 
57   /* %a is poorly specified and as a result some implementations trim
58      redundant trailing zeros (e.g., Glibc) and others don't (e.g.,
59      Solaris).  */
60   T (0, "%.*a", INT_MIN, 0.);     /* { dg-warning "writing between 6 and 20 bytes" } */
61 
62   T (0, "%.*a", INT_MAX, 0.);     /* { dg-warning "writing 2147483654 bytes" } */
63 
64   T (0, "%*.*a", INT_MIN, INT_MIN, 0.);   /* { dg-warning "writing 2147483648 bytes" } */
65 
66   T (0, "%*.*a", INT_MAX, INT_MAX, 0.);   /* { dg-warning "writing 2147483654 bytes" } */
67 }
68 
test_floating_a_var(double x)69 void test_floating_a_var (double x)
70 {
71   T (0, "%*a",  INT_MIN, x);     /* { dg-warning "writing 2147483648 bytes" } */
72   T (0, "%*a",  INT_MAX, x);     /* { dg-warning "writing 2147483647 bytes" } */
73 
74   T (0, "%.*a", INT_MIN, x);     /* { dg-warning "writing between 3 and 24 bytes" } */
75 
76   /* Expected output is "0x0." followed by INT_MAX digits followed by
77      "p+" followed by 1 to four digits, with a byte count in the range
78      [3 + INT_MAX + 2 + 1, 3 + INT_MAX + 2 + 4].  */
79   T (0, "%.*a", INT_MAX, x);     /* { dg-warning "writing between 3 and 2147483658 bytes" } */
80 
81   T (0, "%*.*a", INT_MIN, INT_MIN, x);   /* { dg-warning "writing 2147483648 bytes" } */
82 
83   T (0, "%*.*a", INT_MAX, INT_MAX, x);   /* { dg-warning "writing between 2147483647 and 2147483658 bytes" } */
84 }
85 
test_floating_e_cst(void)86 void test_floating_e_cst (void)
87 {
88   T (0, "%*e",  INT_MIN, 0.);     /* { dg-warning "writing 2147483648 bytes" } */
89   T (0, "%*e",  INT_MAX, 0.);     /* { dg-warning "writing 2147483647 bytes" } */
90 
91   T (0, "%.*e", INT_MIN, 0.);     /* { dg-warning "writing 12 bytes" } */
92 
93   T (0, "%.*e", INT_MAX, 0.);     /* { dg-warning "writing 2147483653 bytes" } */
94 
95   T (0, "%*.*e", INT_MIN, INT_MIN, 0.);   /* { dg-warning "writing 2147483648 bytes" } */
96 
97   T (0, "%*.*e", INT_MAX, INT_MAX, 0.);   /* { dg-warning "writing 2147483653 bytes" } */
98 }
99 
test_floating_e_var(double x)100 void test_floating_e_var (double x)
101 {
102   T (0, "%*e",  INT_MIN, x);     /* { dg-warning "writing 2147483648 bytes" } */
103   T (0, "%*e",  INT_MAX, x);     /* { dg-warning "writing 2147483647 bytes" } */
104 
105   T (0, "%.*e", INT_MIN, x);     /* { dg-warning "writing between 3 and 14 bytes" } */
106 
107   T (0, "%.*e", INT_MAX, x);     /* { dg-warning "writing between 3 and 2147483655 bytes" } */
108 
109   T (0, "%*.*e", INT_MIN, INT_MIN, x);   /* { dg-warning "writing 2147483648 bytes" } */
110 
111   T (0, "%*.*e", INT_MAX, INT_MAX, x);   /* { dg-warning "writing between 2147483647 and 2147483655 bytes" } */
112 }
113 
test_floating_f_cst(void)114 void test_floating_f_cst (void)
115 {
116   T (0, "%*f",  INT_MIN, 0.);     /* { dg-warning "writing 2147483648 bytes" } */
117   T (0, "%*f",  INT_MAX, 0.);     /* { dg-warning "writing 2147483647 bytes" } */
118 
119   T (0, "%.*f", INT_MIN, 0.);     /* { dg-warning "writing 8 bytes" } */
120 
121   T (0, "%.*f", INT_MAX, 0.);     /* { dg-warning "writing 2147483649 bytes" } */
122 
123   T (0, "%*.*f", INT_MIN, INT_MIN, 0.);   /* { dg-warning "writing 2147483648 bytes" } */
124 
125   T (0, "%*.*f", INT_MAX, INT_MAX, 0.);   /* { dg-warning "writing 2147483649 bytes" } */
126 }
127 
test_floating_f_var(double x)128 void test_floating_f_var (double x)
129 {
130   T (0, "%*f",  INT_MIN, x);     /* { dg-warning "writing 2147483648 bytes" } */
131   T (0, "%*f",  INT_MAX, x);     /* { dg-warning "writing 2147483647 bytes" } */
132 
133   T (0, "%.*f", INT_MIN, x);     /* { dg-warning "writing between 3 and 317 bytes" } */
134 
135   T (0, "%.*f", INT_MAX, x);     /* { dg-warning "writing between 3 and 2147483958 bytes" } */
136 
137   T (0, "%*.*f", INT_MIN, INT_MIN, x);   /* { dg-warning "writing 2147483648 bytes" } */
138 
139   T (0, "%*.*f", INT_MAX, INT_MAX, x);   /* { dg-warning "writing between 2147483647 and 2147483958 bytes" } */
140 }
141 
test_floating_g_cst(void)142 void test_floating_g_cst (void)
143 {
144   T (0, "%*g",  INT_MIN, 0.);     /* { dg-warning "writing 2147483648 bytes" } */
145   T (0, "%*g",  INT_MAX, 0.);     /* { dg-warning "writing 2147483647 bytes" } */
146 
147   T (0, "%.*g", INT_MIN, 0.);     /* { dg-warning "writing 1 byte" } */
148 
149   T (0, "%.*g", INT_MAX, 0.);     /* { dg-warning "writing 1 byte" } */
150 
151   T (0, "%*.*g", INT_MIN, INT_MIN, 0.);   /* { dg-warning "writing 2147483648 bytes" } */
152 
153   T (0, "%*.*g", INT_MAX, INT_MAX, 0.);   /* { dg-warning "writing 2147483647 bytes" } */
154 }
155 
test_floating_g(double x)156 void test_floating_g (double x)
157 {
158   T (0, "%*g",  INT_MIN, x);     /* { dg-warning "writing 2147483648 bytes" } */
159   T (0, "%*g",  INT_MAX, x);     /* { dg-warning "writing 2147483647 bytes" } */
160 
161   T (0, "%.*g", INT_MIN, x);     /* { dg-warning "writing between 1 and 13 bytes" } */
162 
163   T (0, "%.*g", INT_MAX, x);     /* { dg-warning "writing between 1 and 310 bytes" } */
164 
165   T (0, "%*.*g", INT_MIN, INT_MIN, x);   /* { dg-warning "writing 2147483648 bytes" } */
166 
167   T (0, "%*.*g", INT_MAX, INT_MAX, x);   /* { dg-warning "writing 2147483647 bytes" } */
168 }
169 
test_string_cst(void)170 void test_string_cst (void)
171 {
172   T (0, "%*s",  INT_MIN, "");     /* { dg-warning "writing 2147483648 bytes" } */
173   T (0, "%*s",  INT_MAX, "");     /* { dg-warning "writing 2147483647 bytes" } */
174 
175   T (0, "%.*s", INT_MIN, "");     /* { dg-warning "writing a terminating nul" } */
176 
177   T (0, "%.*s", INT_MAX, "");     /* { dg-warning "writing a terminating nul" } */
178 
179   T (0, "%*.*s", INT_MIN, INT_MIN, "");   /* { dg-warning "writing 2147483648 bytes" } */
180 
181   T (0, "%*.*s", INT_MAX, INT_MAX, "");   /* { dg-warning "writing 2147483647 bytes" } */
182 }
183 
test_string_var(const char * s)184 void test_string_var (const char *s)
185 {
186   T (0, "%*s",  INT_MIN, s);     /* { dg-warning "writing 2147483648 or more bytes" } */
187   T (0, "%*s",  INT_MAX, s);     /* { dg-warning "writing 2147483647 or more bytes" } */
188 
189   T (0, "%.*s", INT_MIN, s);     /* { dg-warning "writing a terminating nul" } */
190 
191   T (0, "%.*s", INT_MAX, s);     /* { dg-warning "writing up to 2147483647 bytes" } */
192 
193   T (0, "%*.*s", INT_MIN, INT_MIN, s);   /* { dg-warning "writing 2147483648 or more bytes" } */
194 
195   T (0, "%*.*s", INT_MAX, INT_MAX, s);   /* { dg-warning "writing 2147483647 bytes" } */
196 }
197