1 /* PR middle-end/78476 - snprintf(0, 0, ...) with known arguments not
2    optimized away
3    { dg-do compile }
4    { dg-options "-O2 -fdump-tree-optimized" }
5    { dg-require-effective-target int32plus } */
6 
7 #define CAT(s, n)   s ## n
8 #define FAIL(line)  CAT (failure_on_line_, line)
9 #define PASS(line)  CAT (success_on_line_, line)
10 
11 /* Emit a call to a function named failure_on_line_NNN when VALUE
12    is not equal to the constant EXPECTED, otherwise emit a call to
13    function success_on_line_NNN.  */
14 #define ASSERT(value, expected)			\
15   do {						\
16     extern void FAIL (__LINE__)(int);		\
17     extern void PASS (__LINE__)(int);		\
18     if (value == expected)			\
19       PASS (__LINE__)(value);			\
20     else					\
21       FAIL (__LINE__)(value);			\
22   } while (0)
23 
24 /* Verify that EXPECT == snprintf(0, 0, ...).  */
25 #define EQL(expect, ...)				\
26   do {							\
27     int n = __builtin_snprintf (0, 0, __VA_ARGS__);	\
28     ASSERT (n, expect);					\
29   } while (0)
30 
ival(int i)31 static int ival (int i) { return i; }
32 
33 /* Generate a signed int value in the specified range.  */
34 
35 static int
int_range(int min,int max)36 int_range (int min, int max)
37 {
38   extern int int_value (void);
39   int val = int_value ();
40   if (val < min || max < val)
41     val = min;
42   return val;
43 }
44 
45 #define R(min, max) int_range (min, max)
46 
test_arg_int(int i,int n)47 void test_arg_int (int i, int n)
48 {
49   EQL (1, "%i", ival (0));
50   EQL (1, "%i", ival (1));
51   EQL (2, "%i%i", ival (0), ival (1));
52   EQL (3, "%i%i%i", ival (0), ival (1), ival (9));
53   EQL (5, "%i %i %i", ival (0), ival (1), ival (9));
54 
55   EQL (5, "%i %i %i", ival (0), ival (1), ival (9));
56 
57   EQL (13, "%hhu.%hhu.%hhu.%hhu", ival (23), ival (78), ival (216), ival (135));
58 
59   for (i = 0; i != 9; ++i)
60     EQL (1, "%i", i);
61 
62   for (i = -n; i != n; ++i)
63     EQL (8, "%08x", i);
64 
65   /*  As a special case, a precision of zero with an argument of zero
66       results in zero bytes (unless modified by width).  */
67   EQL (0, "%.0d", ival (0));
68   EQL (0, "%.0i", ival (0));
69   EQL (0, "%.0o", ival (0));
70   EQL (0, "%.0u", ival (0));
71   EQL (0, "%.0x", ival (0));
72 
73   EQL (0, "%.*d", 0, ival (0));
74   EQL (0, "%.*i", 0, ival (0));
75   EQL (0, "%.*o", 0, ival (0));
76   EQL (0, "%.*u", 0, ival (0));
77   EQL (0, "%.*x", 0, ival (0));
78 
79   EQL (1, "%1.0d", ival (0));
80   EQL (1, "%1.0i", ival (0));
81   EQL (1, "%1.0o", ival (0));
82   EQL (1, "%1.0u", ival (0));
83   EQL (1, "%1.0x", ival (0));
84 
85   EQL (4, "%hhi", R (-128, -127));
86   EQL (3, "%hhi", R ( -99,  -10));
87   EQL (2, "%hhi", R (  -9,   -1));
88   EQL (1, "%hhi", R (   0,    9));
89   EQL (1, "%hhi", R (   0,    9));
90 
91   EQL (1, "%1.0hhi", R (   0,    1));
92   EQL (1, "%1.1hhi", R (   0,    9));
93   EQL (2, "%1.2hhi", R (   0,    9));
94   EQL (3, "%1.3hhi", R (   0,    9));
95 
96   EQL (1, "%hhi", R (1024, 1033));
97   EQL (2, "%hhi", R (1034, 1123));
98   EQL (1, "%hhu", R (1024, 1033));
99   EQL (2, "%hhu", R (1034, 1123));
100 }
101 
test_arg_string(const char * s)102 void test_arg_string (const char *s)
103 {
104   EQL ( 0, "%-s", "");
105   EQL ( 1, "%%");
106   EQL ( 1, "%-s", "1");
107   EQL ( 2, "%-s", "12");
108   EQL ( 3, "%-s", "123");
109   EQL ( 5, "s=%s", "123");
110   EQL (10, "%%s=\"%s\"", "12345");
111 
112   EQL ( 1, "%.*s", 1, "123");
113   EQL ( 2, "%.*s", 2, "123");
114   EQL ( 3, "%.*s", 3, "123");
115   EQL ( 3, "%.*s", 4, "123");
116 
117   EQL ( 1, "%1.*s", 1, "123");
118   EQL ( 2, "%1.*s", 2, "123");
119   EQL ( 3, "%1.*s", 3, "123");
120   EQL ( 3, "%1.*s", 4, "123");
121   EQL ( 4, "%4.*s", 1, "123");
122   EQL ( 4, "%4.*s", 2, "123");
123   EQL ( 4, "%4.*s", 3, "123");
124   EQL ( 4, "%4.*s", 4, "123");
125   EQL ( 4, "%4.*s", 5, "123");
126 
127   const char *a = "123";
128   const char *b = "456";
129 
130   EQL ( 3, "%-s", s ? a : b);
131   EQL ( 0, "%.0s", s);
132   EQL ( 1, "%1.1s", s);
133   EQL ( 2, "%2.2s", s);
134   EQL ( 2, "%2.1s", s);
135 }
136 
test_arg_multiarg(int i,double d)137 void test_arg_multiarg (int i, double d)
138 {
139   EQL (16, "%12i %s", i, "abc");
140   EQL (16, "%*i %s", 12, i, "abc");
141 }
142 
143 /* Verify that EXPECT == vsnprintf(0, 0, ...).  */
144 #define EQLv(expect, fmt, va)				\
145   do {							\
146     int n = __builtin_vsnprintf (0, 0, fmt, va);	\
147     ASSERT (n, expect);					\
148   } while (0)
149 
test_va_int(__builtin_va_list va)150 void test_va_int (__builtin_va_list va)
151 {
152   EQLv ( 2, "%02hhx", va);
153   EQLv ( 4, "%04hx", va);
154 }
155 
test_va_multiarg(__builtin_va_list va)156 void test_va_multiarg (__builtin_va_list va)
157 {
158   EQLv ( 8, "%8x", va);
159   EQLv ( 8, "% 8x", va);
160   EQLv ( 9, "%9x", va);
161   EQLv (11, "%11o", va);
162   EQLv (12, "%12o", va);
163 
164   EQLv (16, "%12i %3.2s", va);
165 }
166 
167 
168 /* { dg-final { scan-tree-dump-not "failure_on_line" "optimized"} }
169    { dg-final { scan-tree-dump-not "snprintf" "optimized"} } */
170