annotate gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-14.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* PR middle-end/79376 - wrong lower bound with %s and non-constant
kono
parents:
diff changeset
2 strings in -Wformat-overflow
kono
parents:
diff changeset
3 { dg-do compile }
kono
parents:
diff changeset
4 { dg-options "-O2 -Wall -Wformat-overflow=1 -ftrack-macro-expansion=0" } */
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 typedef __SIZE_TYPE__ size_t;
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 #define INT_MAX __INT_MAX__
kono
parents:
diff changeset
9 #define INT_MIN (-INT_MAX - 1)
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 /* When debugging, define LINE to the line number of the test case to exercise
kono
parents:
diff changeset
12 and avoid exercising any of the others. The buffer and objsize macros
kono
parents:
diff changeset
13 below make use of LINE to avoid warnings for other lines. */
kono
parents:
diff changeset
14 #ifndef LINE
kono
parents:
diff changeset
15 # define LINE 0
kono
parents:
diff changeset
16 #endif
kono
parents:
diff changeset
17
kono
parents:
diff changeset
18 extern int int_value (void);
kono
parents:
diff changeset
19
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
20 static int int_range (int min, int max)
111
kono
parents:
diff changeset
21 {
kono
parents:
diff changeset
22 int n = int_value ();
kono
parents:
diff changeset
23 return n < min || max < n ? min : n;
kono
parents:
diff changeset
24 }
kono
parents:
diff changeset
25
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
26 static const char*
111
kono
parents:
diff changeset
27 choose_string (const char *s1, const char *s2, const char *s3)
kono
parents:
diff changeset
28 {
kono
parents:
diff changeset
29 int i = int_value ();
kono
parents:
diff changeset
30 return i < 0 ? s1 : 0 < i ? s3 : s2;
kono
parents:
diff changeset
31 }
kono
parents:
diff changeset
32
kono
parents:
diff changeset
33 void sink (char*, char*);
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 int dummy_sprintf (char*, const char*, ...);
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 char buffer [256];
kono
parents:
diff changeset
38 extern char *ptr;
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 const char s0[] = "";
kono
parents:
diff changeset
41 const char s1[] = "1";
kono
parents:
diff changeset
42 const char s2[] = "12";
kono
parents:
diff changeset
43 const char s3[] = "123";
kono
parents:
diff changeset
44 const char s4[] = "1234";
kono
parents:
diff changeset
45 const char s5[] = "12345";
kono
parents:
diff changeset
46 const char s6[] = "123456";
kono
parents:
diff changeset
47 const char s7[] = "1234567";
kono
parents:
diff changeset
48 const char s8[] = "12345678";
kono
parents:
diff changeset
49 const char s9[] = "123456789";
kono
parents:
diff changeset
50 extern const char sx[];
kono
parents:
diff changeset
51 extern const char sy[];
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 /* Evaluate to an array of SIZE characters when non-negative, or to
kono
parents:
diff changeset
54 a pointer to an unknown object otherwise. */
kono
parents:
diff changeset
55 #define buffer(size) \
kono
parents:
diff changeset
56 ((0 <= size) ? buffer + sizeof buffer - (size) : ptr)
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 /* Helper to expand function to either __builtin_f or dummy_f to
kono
parents:
diff changeset
59 make debugging GCC easy. */
kono
parents:
diff changeset
60 #define FUNC(f) \
kono
parents:
diff changeset
61 ((!LINE || LINE == __LINE__) ? __builtin_ ## f : dummy_ ## f)
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63 /* Macro to verify that calls to __builtin_sprintf (i.e., with no size
kono
parents:
diff changeset
64 argument) issue diagnostics by correctly determining the size of
kono
parents:
diff changeset
65 the destination buffer. */
kono
parents:
diff changeset
66 #define T(size, ...) \
kono
parents:
diff changeset
67 (FUNC (sprintf) (buffer (size), __VA_ARGS__), \
kono
parents:
diff changeset
68 sink (buffer, ptr))
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 /* Return a value in the range [MIN, MAX]. */
kono
parents:
diff changeset
71 #define R(min, max) int_range (min, max)
kono
parents:
diff changeset
72
kono
parents:
diff changeset
73 /* Return one of the strings S1, S2, S3. */
kono
parents:
diff changeset
74 #define S(s1, s2, s3) choose_string (s1, s2, s3)
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 struct S {
kono
parents:
diff changeset
77 char a1[1];
kono
parents:
diff changeset
78 char a2[2];
kono
parents:
diff changeset
79 char a3[3];
kono
parents:
diff changeset
80 char a4[4];
kono
parents:
diff changeset
81 char a5[5];
kono
parents:
diff changeset
82 char ax[];
kono
parents:
diff changeset
83 };
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 void test_strings (struct S *s)
kono
parents:
diff changeset
86 {
kono
parents:
diff changeset
87 T (0, "%-s", S (s->a1, s->a1, s1)); /* { dg-warning "writing up to 1 byte" } */
kono
parents:
diff changeset
88 T (0, "%-s", S (s->a1, s->a2, s1)); /* { dg-warning "writing up to 1 byte" } */
kono
parents:
diff changeset
89 T (0, "%-s", S (s->a2, s->a1, s1)); /* { dg-warning "writing up to 1 byte" } */
kono
parents:
diff changeset
90
kono
parents:
diff changeset
91 T (0, "%-s", S (s->a1, s1, s->a1)); /* { dg-warning "writing up to 1 byte" } */
kono
parents:
diff changeset
92 T (0, "%-s", S (s->a1, s1, s->a2)); /* { dg-warning "writing up to 1 byte" } */
kono
parents:
diff changeset
93 T (0, "%-s", S (s->a2, s1, s->a1)); /* { dg-warning "writing up to 1 byte" } */
kono
parents:
diff changeset
94
kono
parents:
diff changeset
95 T (0, "%-s", S (s1, s->a1, s1)); /* { dg-warning "writing up to 1 byte" } */
kono
parents:
diff changeset
96 T (0, "%-s", S (s1, s->a1, s1)); /* { dg-warning "writing up to 1 byte" } */
kono
parents:
diff changeset
97 T (0, "%-s", S (s1, s->a2, s1)); /* { dg-warning "writing up to 1 byte" } */
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 T (0, "%-s", S (s->a1, s->a1, s2)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
100 T (0, "%-s", S (s->a1, s->a2, s2)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
101 T (0, "%-s", S (s->a2, s->a1, s2)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
102
kono
parents:
diff changeset
103 T (0, "%-s", S (s->a1, s2, s->a1)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
104 T (0, "%-s", S (s->a1, s2, s->a2)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
105 T (0, "%-s", S (s->a2, s2, s->a1)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107 T (0, "%-s", S (s2, s->a1, s1)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
108 T (0, "%-s", S (s2, s->a1, s1)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
109 T (0, "%-s", S (s2, s->a2, s1)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
110
kono
parents:
diff changeset
111 T (0, "%-s", S (s->a1, s->a1, s2)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
112 T (0, "%-s", S (s->a1, s->a2, s2)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
113 T (0, "%-s", S (s->a2, s->a1, s2)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 T (0, "%-s", S (s->a1, s2, s->a1)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
116 T (0, "%-s", S (s->a1, s2, s->a2)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
117 T (0, "%-s", S (s->a2, s2, s->a1)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119 T (0, "%-s", S (s2, s->a1, s1)); /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
120 T (0, "%-s", S (s3, s->a1, s2)); /* { dg-warning "writing up to 3 bytes" } */
kono
parents:
diff changeset
121 T (0, "%-s", S (s4, s->a2, s3)); /* { dg-warning "writing up to 4 bytes" } */
kono
parents:
diff changeset
122
kono
parents:
diff changeset
123 T (0, "%-s", S (s->a3, s->a5, s3)); /* { dg-warning "writing up to 4 bytes" } */
kono
parents:
diff changeset
124 T (0, "%-s", S (s->a3, s->a5, s3)); /* { dg-warning "writing up to 4 bytes" } */
kono
parents:
diff changeset
125 T (0, "%-s", S (s->a3, s->a5, s3)); /* { dg-warning "writing up to 4 bytes" } */
kono
parents:
diff changeset
126
kono
parents:
diff changeset
127 T (0, "%-s", S (s->a3, s3, s->a5)); /* { dg-warning "writing up to 4 bytes" } */
kono
parents:
diff changeset
128 T (0, "%-s", S (s->a5, s3, s->a3)); /* { dg-warning "writing up to 4 bytes" } */
kono
parents:
diff changeset
129 T (0, "%-s", S (s->a3, s3, s->a5)); /* { dg-warning "writing up to 4 bytes" } */
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 T (0, "%-s", S (s3, s->a1, s4)); /* { dg-warning "writing up to 4 bytes" } */
kono
parents:
diff changeset
132 T (0, "%-s", S (s4, s->a2, s3)); /* { dg-warning "writing up to 4 bytes" } */
kono
parents:
diff changeset
133 }
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 void test_strings_with_width (struct S *s)
kono
parents:
diff changeset
136 {
kono
parents:
diff changeset
137 T (0, "%*s", /* { dg-warning "writing up to 4 bytes" } */
kono
parents:
diff changeset
138 R (0, 1),
kono
parents:
diff changeset
139 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 T (0, "%*s", /* { dg-warning "writing up to 4 bytes" } */
kono
parents:
diff changeset
142 R (0, 4),
kono
parents:
diff changeset
143 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 T (0, "%*s", /* { dg-warning "writing between 1 and 4 bytes" } */
kono
parents:
diff changeset
146 R (1, 4),
kono
parents:
diff changeset
147 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 T (0, "%*s", /* { dg-warning "writing between 2 and 4 bytes" } */
kono
parents:
diff changeset
150 R (2, 4),
kono
parents:
diff changeset
151 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 T (0, "%*s", /* { dg-warning "writing between 3 and 4 bytes" } */
kono
parents:
diff changeset
154 R (3, 4),
kono
parents:
diff changeset
155 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157 T (0, "%*s", /* { dg-warning "writing between 3 and 5 bytes" } */
kono
parents:
diff changeset
158 R (3, 5),
kono
parents:
diff changeset
159 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 T (0, "%*s", /* { dg-warning "writing between 3 and 9 bytes" } */
kono
parents:
diff changeset
162 R (3, 9),
kono
parents:
diff changeset
163 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165 T (3, "%*s", /* { dg-warning "writing between 3 and 9 bytes" } */
kono
parents:
diff changeset
166 R (3, 9),
kono
parents:
diff changeset
167 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 /* The longest string fits but the terminating nul will overflow. Since
kono
parents:
diff changeset
170 the null won't overflow with the shorter strings the warning is a "may
kono
parents:
diff changeset
171 write." */
kono
parents:
diff changeset
172 T (4, "%*s", /* { dg-warning "may write a terminating nul" } */
kono
parents:
diff changeset
173 R (3, 9),
kono
parents:
diff changeset
174 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
175 }
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 void test_strings_with_width_and_precisin (struct S *s)
kono
parents:
diff changeset
178 {
kono
parents:
diff changeset
179 T (0, "%*.*s", /* { dg-warning "writing up to 1 byte" } */
kono
parents:
diff changeset
180 R (0, 1),
kono
parents:
diff changeset
181 R (0, 1),
kono
parents:
diff changeset
182 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
183
kono
parents:
diff changeset
184 T (0, "%*.*s", /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
185 R (0, 2),
kono
parents:
diff changeset
186 R (0, 1),
kono
parents:
diff changeset
187 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
188
kono
parents:
diff changeset
189 T (0, "%*.*s", /* { dg-warning "writing up to 9 bytes" } */
kono
parents:
diff changeset
190 R (0, 9),
kono
parents:
diff changeset
191 R (0, 1),
kono
parents:
diff changeset
192 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 /* Since the longest string/array fits there is no warning even if
kono
parents:
diff changeset
195 the maximum width would cause overflow. */
kono
parents:
diff changeset
196 T (6, "%*.*s",
kono
parents:
diff changeset
197 R (0, 9),
kono
parents:
diff changeset
198 R (0, 1),
kono
parents:
diff changeset
199 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
200
kono
parents:
diff changeset
201 T (0, "%*.*s", /* { dg-warning "writing up to 2 bytes" } */
kono
parents:
diff changeset
202 R (0, 2),
kono
parents:
diff changeset
203 R (0, 2),
kono
parents:
diff changeset
204 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 T (0, "%*.*s", /* { dg-warning "writing up to 3 bytes" } */
kono
parents:
diff changeset
207 R (0, 3),
kono
parents:
diff changeset
208 R (0, 2),
kono
parents:
diff changeset
209 S (s->a3, s->a5, s3));
kono
parents:
diff changeset
210 }