]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-4.c
Fix profile update in tree_transform_and_unroll_loop
[thirdparty/gcc.git] / gcc / testsuite / gcc.dg / tree-ssa / builtin-snprintf-4.c
CommitLineData
3e6837c2
MS
1/* PR tree-optimization/87096 - "Optimised" snprintf is not POSIX conformant
2 Verify that calls to snprintf with size in excess of INT_MAX are not
3 treated as successful.
4 It would be valid for GCC to fold some of these calls to a negative
5 value provided it also arranged to set errno to EOVERFLOW. If that
6 is ever implemented this test will need to be adjusted.
7 { dg-do compile }
8 { dg-options "-O2 -Wall -fdump-tree-optimized -ftrack-macro-expansion=0" } */
9
10#include "../range.h"
11
12typedef __builtin_va_list va_list;
13
14extern int snprintf (char*, size_t, const char*, ...);
15extern int vsnprintf (char*, size_t, const char*, va_list);
16
17#define CAT(x, y) x ## y
18#define CONCAT(x, y) CAT (x, y)
19#define FAILNAME(name) CONCAT (call_ ## name ##_on_line_, __LINE__)
20
21#define FAIL(name) do { \
22 extern void FAILNAME (name) (void); \
23 FAILNAME (name)(); \
24 } while (0)
25
26/* Macro to emit a call to function named
27 call_in_true_branch_not_eliminated_on_line_NNN()
28 for each expression that's expected to fold to false but that
29 GCC does not fold. The dg-final scan-tree-dump-time directive
30 at the bottom of the test verifies that no such call appears
31 in output. */
32#define ELIM(expr) \
33 if ((expr)) FAIL (in_true_branch_not_eliminated); else (void)0
34
35/* Macro to emit a call to a function named
36 call_made_in_{true,false}_branch_on_line_NNN()
37 for each call that's expected to be retained. The dg-final
38 scan-tree-dump-time directive at the bottom of the test verifies
39 that the expected number of both kinds of calls appears in output
40 (a pair for each line with the invocation of the KEEP() macro. */
41#define KEEP(expr) \
42 if (expr) \
43 FAIL (made_in_true_branch); \
44 else \
45 FAIL (made_in_false_branch)
46
47extern void sink (int, ...);
48#define sink(...) sink (0, __VA_ARGS__)
49
50#define WARN(N, expr) \
51 do { \
52 char a[N]; \
53 expr; \
54 sink (a); \
55 } while (0)
56
57
58static const size_t imax = __INT_MAX__;
59static const size_t imaxp1 = imax + 1;
60
22b04f05
MS
61#if __PTRDIFF_MAX__ == __INT_MAX__
62/* Make the test pass on ILP32 the same way it does on LP64. */
63static const size_t dmax = __PTRDIFF_MAX__ + (size_t)1;
64#else
3e6837c2 65static const size_t dmax = __PTRDIFF_MAX__;
22b04f05 66#endif
3e6837c2
MS
67static const size_t dmaxp1 = dmax + 1;
68
69static const size_t szmax = __SIZE_MAX__;
70static const size_t szmaxm1 = __SIZE_MAX__ - 1;
71
72
73void test_size_cst (char **d)
74{
75 ELIM (0 > snprintf (*d++, imax, "%s", ""));
76
77 KEEP (0 > snprintf (*d++, imaxp1, "%s", "")); /* { dg-warning "\\\[-Wformat-truncation=]" } */
78
79 KEEP (0 > snprintf (*d++, dmax, "%s", "")); /* { dg-warning "\\\[-Wformat-truncation=]" } */
80 KEEP (0 > snprintf (*d++, dmaxp1, "%s", "")); /* { dg-warning "\\\[-Wformat-truncation=]" } */
81 KEEP (0 > snprintf (*d++, szmaxm1, "%s", "")); /* { dg-warning "\\\[-Wformat-truncation=]" } */
82 KEEP (0 > snprintf (*d++, szmax, "%s", "")); /* { dg-warning "\\\[-Wformat-truncation=]" } */
83}
84
85
86void test_size_cst_va (char **d, va_list va)
87{
88 ELIM (0 > vsnprintf (*d++, imax, " ", va));
89
90 KEEP (0 > vsnprintf (*d++, imaxp1, " ", va)); /* { dg-warning "\\\[-Wformat-truncation=]" } */
91
92 KEEP (0 > vsnprintf (*d++, dmax, " ", va)); /* { dg-warning "\\\[-Wformat-truncation=]" } */
93 KEEP (0 > vsnprintf (*d++, dmaxp1, " ", va)); /* { dg-warning "\\\[-Wformat-truncation=]" } */
94 KEEP (0 > vsnprintf (*d++, szmaxm1, " ", va)); /* { dg-warning "\\\[-Wformat-truncation=]" } */
95 KEEP (0 > vsnprintf (*d++, szmax, " ", va)); /* { dg-warning "\\\[-Wformat-truncation=]" } */
96}
97
98
99void test_size_range (char **d)
100{
101 size_t r = UR (imax - 1, imax);
102 ELIM (0 > snprintf (*d++, r, "%s", ""));
103
104 r = UR (imax, imax + 1);
105 KEEP (0 > snprintf (*d++, r, "%s", ""));
106
107 r = UR (imaxp1, imaxp1 + 1);
108 KEEP (0 > snprintf (*d++, r, "%s", "")); /* { dg-warning "specified bound range \\\[\[0-9\]+, \[0-9\]+] exceeds .INT_MAX." } */
109
110 r = UR (dmax, dmaxp1);
111 KEEP (0 > snprintf (*d++, r, "%s", "")); /* { dg-warning "\\\[-Wformat-truncation=]" } */
112
113 r = UR (dmaxp1, dmaxp1 + 1);
114 KEEP (0 > snprintf (*d++, r, "%s", "")); /* { dg-warning "\\\[-Wformat-truncation=]" } */
115
116 r = UR (szmaxm1, szmax);
117 KEEP (0 > snprintf (*d++, r, "%s", "")); /* { dg-warning "\\\[-Wformat-truncation=]" } */
118}
119
120
121void test_size_range_va (char **d, va_list va)
122{
123 size_t r = UR (imax - 1, imax);
124 ELIM (0 > vsnprintf (*d++, r, " ", va));
125
126 r = UR (imax, imax + 1);
127 KEEP (0 > vsnprintf (*d++, r, " ", va));
128
129 r = UR (imaxp1, imaxp1 + 1);
130 KEEP (0 > vsnprintf (*d++, r, " ", va)); /* { dg-warning "specified bound range \\\[\[0-9\]+, \[0-9\]+] exceeds .INT_MAX." } */
131
132 r = UR (dmax, dmaxp1);
133 KEEP (0 > vsnprintf (*d++, r, " ", va)); /* { dg-warning "\\\[-Wformat-truncation=]" } */
134
135 r = UR (dmaxp1, dmaxp1 + 1);
136 KEEP (0 > vsnprintf (*d++, r, " ", va)); /* { dg-warning "\\\[-Wformat-truncation=]" } */
137
138 r = UR (szmaxm1, szmax);
139 KEEP (0 > vsnprintf (*d++, r, " ", va)); /* { dg-warning "\\\[-Wformat-truncation=]" } */
140}
141
142
143void test_size_varying (char **d, size_t n)
144{
145 KEEP (0 > snprintf (*d++, n, "%s", ""));
146
147 n += 1;
148 KEEP (0 > snprintf (*d++, n, "%s", ""));
149}
150
151
152void test_size_varying_va (char **d, size_t n, va_list va)
153{
154 KEEP (0 > vsnprintf (*d++, n, " ", va));
155
156 n += 1;
157 KEEP (0 > vsnprintf (*d++, n, " ", va));
158}
159
160/* { dg-final { scan-tree-dump-times " = snprintf" 12 "optimized"} }
161 { dg-final { scan-tree-dump-times " = vsnprintf" 12 "optimized"} } */