annotate gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-6.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +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/78476 - snprintf(0, 0, ...) with known arguments not
kono
parents:
diff changeset
2 optimized away
kono
parents:
diff changeset
3 PR middle-end/78512 - r242674 miscompiles Linux kernel
kono
parents:
diff changeset
4 A negative test complementing builtin-sprintf-5.c to verify that calls
kono
parents:
diff changeset
5 to the function that do not return a constant are not optimized away.
kono
parents:
diff changeset
6 Test also verifies that unknown directives prevent the optimization.
kono
parents:
diff changeset
7 { dg-do compile }
kono
parents:
diff changeset
8 { dg-options "-O2 -Wformat -fdump-tree-optimized" }
kono
parents:
diff changeset
9 { dg-require-effective-target int32plus } */
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 typedef __SIZE_TYPE__ size_t;
kono
parents:
diff changeset
12
kono
parents:
diff changeset
13 #define CONCAT(a, b) a ## b
kono
parents:
diff changeset
14 #define CAT(a, b) CONCAT (a, b)
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 #define T(...) \
kono
parents:
diff changeset
17 do { \
kono
parents:
diff changeset
18 int CAT (n, __LINE__) = __builtin_snprintf (0, 0, __VA_ARGS__); \
kono
parents:
diff changeset
19 sink (CAT (n, __LINE__)); \
kono
parents:
diff changeset
20 } while (0)
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 void sink (int);
kono
parents:
diff changeset
23
kono
parents:
diff changeset
24 static int
kono
parents:
diff changeset
25 int_range (int min, int max)
kono
parents:
diff changeset
26 {
kono
parents:
diff changeset
27 extern int int_value (void);
kono
parents:
diff changeset
28 int val = int_value ();
kono
parents:
diff changeset
29 if (val < min || max < val)
kono
parents:
diff changeset
30 val = min;
kono
parents:
diff changeset
31 return val;
kono
parents:
diff changeset
32 }
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 #define R(min, max) int_range (min, max)
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 void test_arg_int (int width, int prec, int i, int n)
kono
parents:
diff changeset
37 {
kono
parents:
diff changeset
38 T ("%i", i);
kono
parents:
diff changeset
39 T ("%1i", i);
kono
parents:
diff changeset
40 T ("%2i", i);
kono
parents:
diff changeset
41 T ("%3i", i);
kono
parents:
diff changeset
42 T ("%4i", i);
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 T ("%*i", width, 0);
kono
parents:
diff changeset
45 T ("%*i", width, 1);
kono
parents:
diff changeset
46 T ("%*i", width, i);
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 T ("%.*i", prec, 0);
kono
parents:
diff changeset
49 T ("%.*i", prec, 1);
kono
parents:
diff changeset
50 T ("%.*i", prec, i);
kono
parents:
diff changeset
51 T ("%.*i", 0, i);
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 T ("%i", R (1, 10));
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55 /* Each of the bounds of the ranges below results in just one byte
kono
parents:
diff changeset
56 on output because they convert to the value 9 in type char, yet
kono
parents:
diff changeset
57 other values in those ranges can result in up to four bytes.
kono
parents:
diff changeset
58 For example, 4240 converts to -112. Verify that the output
kono
parents:
diff changeset
59 isn't folded into a constant. This assumes __CHAR_BIT__ of 8. */
kono
parents:
diff changeset
60 T ("%hhi", R (4104, 4360) + 1);
kono
parents:
diff changeset
61 T ("%hhu", R (4104, 4360) + 1);
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63 /* Here, the range includes all possible lengths of output for
kono
parents:
diff changeset
64 a 16-bit short and 32-bit int. */
kono
parents:
diff changeset
65 T ("%hi", R (65536, 65536 * 2));
kono
parents:
diff changeset
66 T ("%hu", R (65536, 65536 * 2));
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 T ("%'i", 1234567);
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 for (i = -n; i != n; ++i)
kono
parents:
diff changeset
71 T ("%*x", n, i);
kono
parents:
diff changeset
72 }
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 /* Support for %p was removed in response to PR middle-end/78512 due
kono
parents:
diff changeset
75 to the Linux kernel relying on GCC builtins while at the same time
kono
parents:
diff changeset
76 providing a large number of extensions to the %p directive that
kono
parents:
diff changeset
77 interfere with the optimization. Verify that %p disables it. */
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 void test_arg_ptr (int width, int prec, int i)
kono
parents:
diff changeset
80 {
kono
parents:
diff changeset
81 T ("%p", (void*)0);
kono
parents:
diff changeset
82 T ("p=%p", (void*)0);
kono
parents:
diff changeset
83 T ("%s=%p", "p=", (void*)0);
kono
parents:
diff changeset
84 T ("%i%p", 123, (void*)0);
kono
parents:
diff changeset
85 }
kono
parents:
diff changeset
86
kono
parents:
diff changeset
87 void test_arg_string (int width, int prec, const char *s)
kono
parents:
diff changeset
88 {
kono
parents:
diff changeset
89 T ("%-s", s);
kono
parents:
diff changeset
90 T ("%1s", s);
kono
parents:
diff changeset
91 T ("%.1s", s);
kono
parents:
diff changeset
92 T ("%*s", width, s);
kono
parents:
diff changeset
93 T ("%.*s", prec, s);
kono
parents:
diff changeset
94 T ("%1.*s", prec, s);
kono
parents:
diff changeset
95 T ("%*.1s", width, s);
kono
parents:
diff changeset
96 T ("%*.*s", width, prec, s);
kono
parents:
diff changeset
97 T ("%*s", width, "123");
kono
parents:
diff changeset
98 T ("%.*s", prec, "123");
kono
parents:
diff changeset
99 T ("%1.*s", prec, "123");
kono
parents:
diff changeset
100 T ("%*.1s", width, "123");
kono
parents:
diff changeset
101 T ("%*.*s", width, prec, "123");
kono
parents:
diff changeset
102 }
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 void test_invalid_directive (void)
kono
parents:
diff changeset
105 {
kono
parents:
diff changeset
106 T ("%"); /* { dg-warning "spurious trailing .%." } */
kono
parents:
diff changeset
107 T ("abc%"); /* { dg-warning "spurious trailing .%." } */
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 T ("%2$i"); /* { dg-warning "operand number out of range" } */
kono
parents:
diff changeset
110 T ("abc%2$i"); /* { dg-warning "operand number out of range" } */
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 T ("%=i", 0); /* { dg-warning "unknown conversion type character .=." } */
kono
parents:
diff changeset
113 /* { dg-warning "too many arguments" "" { target *-*-* } .-1 } */
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 T ("%*i", "", 0); /* { dg-warning "field width specifier .\\*. expects argument of type .int." } */
kono
parents:
diff changeset
116 T ("%.*i", "", 0); /* { dg-warning "field precision specifier .\\.\\*. expects argument of type .int." } */
kono
parents:
diff changeset
117 T ("%.*.i", 0); /* { dg-warning "unknown conversion type character .\\.." } */
kono
parents:
diff changeset
118 T ("%Q"); /* { dg-warning "unknown conversion type character .Q." } */
kono
parents:
diff changeset
119 T ("abc%Q"); /* { dg-warning "unknown conversion type character .Q." } */
kono
parents:
diff changeset
120 }
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122
kono
parents:
diff changeset
123 /* Use 'grep "^ *T (" builtin-sprintf-6.c | wc -l' to determine
kono
parents:
diff changeset
124 the count for the directive below.
kono
parents:
diff changeset
125 { dg-final { scan-tree-dump-times "snprintf" 46 "optimized"} } */