Mercurial > hg > CbC > CbC_gcc
comparison gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-9.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* { dg-do compile } */ | |
2 /* { dg-options "-O2 -Wformat -Wformat-overflow=2 -ftrack-macro-expansion=0" } */ | |
3 | |
4 typedef __SIZE_TYPE__ size_t; | |
5 | |
6 #define INT_MAX __INT_MAX__ | |
7 #define INT_MIN (-INT_MAX - 1) | |
8 | |
9 #ifndef LINE | |
10 # define LINE 0 | |
11 #endif | |
12 | |
13 int dummy_sprintf (char*, const char*, ...); | |
14 void sink (void*); | |
15 | |
16 char buffer[4096]; | |
17 char *ptr; | |
18 | |
19 /* Helper to expand function to either __builtin_f or dummy_f to | |
20 make debugging GCC easy. */ | |
21 #define FUNC(f) \ | |
22 ((!LINE || LINE == __LINE__) ? __builtin_ ## f : dummy_ ## f) | |
23 | |
24 /* Evaluate to an array of SIZE characters when non-negative, or to | |
25 a pointer to an unknown object otherwise. */ | |
26 #define buffer(size) \ | |
27 ((0 <= size) ? buffer + sizeof buffer - (size) : ptr) | |
28 | |
29 #define T(bufsize, fmt, ...) \ | |
30 do { \ | |
31 char *buf = buffer (bufsize); \ | |
32 FUNC (sprintf)(buf, fmt, __VA_ARGS__); \ | |
33 sink (buf); \ | |
34 } while (0) | |
35 | |
36 | |
37 /* Identity function to verify that the checker figures out the value | |
38 of the operand even when it's not constant (i.e., makes use of | |
39 inlining and constant propagation information). */ | |
40 | |
41 int i (int x) { return x; } | |
42 const char* s (const char *str) { return str; } | |
43 | |
44 /* Function to "generate" a unique unknown number (as far as GCC can | |
45 tell) each time it's called. It prevents the optimizer from being | |
46 able to narrow down the ranges of possible values in test functions | |
47 with repeated references to the same variable. */ | |
48 extern int value (void); | |
49 | |
50 /* Return a value in the range [MIN, MAX]. */ | |
51 int range (int min, int max) | |
52 { | |
53 int val = value (); | |
54 return val < min || max < val ? min : val; | |
55 } | |
56 | |
57 #define R(min, max) range (min, max) | |
58 | |
59 /* Verify that the checker can detect buffer overflow when the "%s" | |
60 argument is in a known range of lengths and one or both of which | |
61 exceed the size of the destination. */ | |
62 | |
63 void test_sprintf_chk_string (const char *s) | |
64 { | |
65 T (1, "%*s", R (0, 1), ""); /* { dg-warning "may write a terminating nul" } */ | |
66 T (1, "%*s", R (-2, -1), ""); /* { dg-warning "writing up to 2 bytes" } */ | |
67 T (1, "%*s", R (-3, 2), ""); /* { dg-warning "writing up to 3 bytes" } */ | |
68 T (1, "%*s", R (-4, 5), ""); /* { dg-warning "writing up to 5 bytes" } */ | |
69 | |
70 T (1, "%*s", R ( -5, 6), "1"); /* { dg-warning "writing between 1 and 6 bytes" } */ | |
71 T (1, "%*s", R ( -6, 7), "12"); /* { dg-warning "writing between 2 and 7 bytes" } */ | |
72 | |
73 T (1, "%.*s", R (0, 1), ""); | |
74 T (1, "%.*s", R (0, 1), s); /* { dg-warning "may write a terminating nul" } */ | |
75 T (1, "%.*s", R (-2, -1), ""); | |
76 T (1, "%.*s", R (-2, -1), s); /* { dg-warning "may write a terminating nul" } */ | |
77 T (1, "%.*s", R (-3, 2), ""); | |
78 T (1, "%.*s", R (-4, 5), ""); | |
79 | |
80 T (1, "%.*s", R ( -5, 6), "1"); /* { dg-warning "may write a terminating nul" } */ | |
81 T (1, "%.*s", R ( -6, 7), "12"); /* { dg-warning "writing up to 2 bytes " } */ | |
82 T (1, "%.*s", R ( 1, 7), "12"); /* { dg-warning "writing between 1 and 2 bytes " } */ | |
83 T (1, "%.*s", R ( 2, 7), "12"); /* { dg-warning "writing 2 bytes " } */ | |
84 | |
85 T (1, "%*.*s", R (0, 1), R (0, 1), ""); /* { dg-warning "may write a terminating nul" } */ | |
86 T (1, "%*.*s", R (0, 2), R (0, 1), ""); /* { dg-warning "directive writing up to 2 bytes into a region of size 1" } */ | |
87 T (1, "%*.*s", R (0, 3), R (0, 1), ""); /* { dg-warning "writing up to 3 bytes" } */ | |
88 | |
89 T (1, "%*.*s", R (0, 1), R (0, 1), "1"); /* { dg-warning "may write a terminating nul" } */ | |
90 T (1, "%*.*s", R (0, 2), R (0, 1), "1"); /* { dg-warning "writing up to 2 bytes" } */ | |
91 T (1, "%*.*s", R (0, 3), R (0, 1), "1"); /* { dg-warning "writing up to 3 bytes" } */ | |
92 | |
93 T (1, "%*.*s", R (0, 1), R (0, 1), "12"); /* { dg-warning "may write a terminating nul" } */ | |
94 T (1, "%*.*s", R (0, 2), R (0, 1), "12"); /* { dg-warning "writing up to 2 bytes" } */ | |
95 T (1, "%*.*s", R (0, 3), R (0, 1), "12"); /* { dg-warning "writing up to 3 bytes" } */ | |
96 | |
97 T (1, "%*.*s", R (0, 1), R (0, 1), "123"); /* { dg-warning "may write a terminating nul" } */ | |
98 T (1, "%*.*s", R (0, 2), R (0, 1), "123"); /* { dg-warning "writing up to 2 bytes" } */ | |
99 T (1, "%*.*s", R (0, 3), R (0, 1), "123"); /* { dg-warning "writing up to 3 bytes" } */ | |
100 T (1, "%*.*s", R (0, 3), R (0, 1), s); /* { dg-warning "writing up to 3 bytes" } */ | |
101 | |
102 T (1, "%*.*s", R (0, 1), R (0, 2), "123"); /* { dg-warning "writing up to 2 bytes" } */ | |
103 T (1, "%*.*s", R (0, 2), R (0, 2), "123"); /* { dg-warning "writing up to 2 bytes" } */ | |
104 T (1, "%*.*s", R (0, 3), R (0, 2), "123"); /* { dg-warning "writing up to 3 bytes" } */ | |
105 T (1, "%*.*s", R (0, 3), R (0, 2), s); /* { dg-warning "writing up to 3 bytes" } */ | |
106 | |
107 T (1, "%*.*s", R (0, 1), R (0, 3), "123"); /* { dg-warning "writing up to 3 bytes" } */ | |
108 T (1, "%*.*s", R (0, 2), R (0, 3), "123"); /* { dg-warning "writing up to 3 bytes" } */ | |
109 T (1, "%*.*s", R (0, 3), R (0, 3), "123"); /* { dg-warning "writing up to 3 bytes" } */ | |
110 T (1, "%*.*s", R (0, 3), R (0, 3), s); /* { dg-warning "writing up to 3 bytes" } */ | |
111 | |
112 T (1, "%*.*s", R (1, 1), R (0, 3), "123"); /* { dg-warning "writing between 1 and 3 bytes" } */ | |
113 T (1, "%*.*s", R (1, 2), R (0, 3), "123"); /* { dg-warning "writing between 1 and 3 bytes" } */ | |
114 T (1, "%*.*s", R (1, 3), R (0, 3), "123"); /* { dg-warning "writing between 1 and 3 bytes" } */ | |
115 T (1, "%*.*s", R (1, 3), R (0, 3), s); /* { dg-warning "writing between 1 and 3 bytes" } */ | |
116 | |
117 T (1, "%*.*s", R (1, 1), R (1, 3), "123"); /* { dg-warning "writing between 1 and 3 bytes" } */ | |
118 T (1, "%*.*s", R (1, 2), R (1, 3), "123"); /* { dg-warning "writing between 1 and 3 bytes" } */ | |
119 T (1, "%*.*s", R (1, 3), R (1, 3), "123"); /* { dg-warning "writing between 1 and 3 bytes" } */ | |
120 T (1, "%*.*s", R (1, 3), R (1, 3), s); /* { dg-warning "writing between 1 and 3 bytes" } */ | |
121 | |
122 T (1, "%*.*s", R (2, 3), R (1, 3), "123"); /* { dg-warning "writing between 2 and 3 bytes" } */ | |
123 T (1, "%*.*s", R (3, 4), R (1, 3), "123"); /* { dg-warning "writing between 3 and 4 bytes" } */ | |
124 T (1, "%*.*s", R (4, 5), R (1, 3), "123"); /* { dg-warning "writing between 4 and 5 bytes" } */ | |
125 T (1, "%*.*s", R (2, 3), R (1, 3), s); /* { dg-warning "writing between 2 and 3 bytes" } */ | |
126 } | |
127 | |
128 void test_sprintf_chk_int (int w, int p, int i) | |
129 { | |
130 T (1, "%*d", w, 0); /* { dg-warning "may write a terminating nul|directive writing between 1 and \[0-9\]+ bytes" } */ | |
131 T (1, "%*d", w, i); /* { dg-warning "may write a terminating nul|directive writing between 1 and \[0-9\]+ bytes" } */ | |
132 | |
133 T (1, "%*d", R (-1, 1), 0); /* { dg-warning "writing a terminating nul" } */ | |
134 T (1, "%*d", R ( 0, 1), 0); /* { dg-warning "writing a terminating nul" } */ | |
135 T (1, "%+*d", R ( 0, 1), 0); /* { dg-warning "directive writing 2 bytes" } */ | |
136 T (1, "%+*u", R ( 0, 1), 0); /* { dg-warning "writing a terminating nul" } */ | |
137 T (2, "%*d", R (-3, -2), 0); /* { dg-warning "directive writing between 1 and 3 bytes" } */ | |
138 T (2, "%*d", R (-3, -1), 0); /* { dg-warning "directive writing between 1 and 3 bytes" } */ | |
139 T (2, "%*d", R (-3, 0), 0); /* { dg-warning "directive writing between 1 and 3 bytes" } */ | |
140 T (2, "%*d", R (-2, -1), 0); /* { dg-warning "may write a terminating nul" } */ | |
141 T (2, "%*d", R (-2, 2), 0); /* { dg-warning "may write a terminating nul" } */ | |
142 T (2, "%*d", R (-1, 2), 0); /* { dg-warning "may write a terminating nul" } */ | |
143 T (2, "%*d", R ( 0, 2), 0); /* { dg-warning "may write a terminating nul" } */ | |
144 T (2, "%*d", R ( 1, 2), 0); /* { dg-warning "may write a terminating nul" } */ | |
145 | |
146 T (1, "%.*d", p, 0); /* { dg-warning "may write a terminating nul|directive writing up to \[0-9\]+ bytes" } */ | |
147 T (1, "%.*d", p, i); /* { dg-warning "may write a terminating nul||directive writing up to \[0-9\]+ bytes" } */ | |
148 T (1, "%.*d", R (INT_MIN, -1), 0); /* { dg-warning "writing a terminating nul" } */ | |
149 T (1, "%.*d", R (INT_MIN, 0), 0); /* { dg-warning "may write a terminating nul" } */ | |
150 T (1, "%.*d", R (-2, -1), 0); /* { dg-warning "writing a terminating nul" } */ | |
151 T (1, "%.*d", R (-1, 1), 0); /* { dg-warning "may write a terminating nul" } */ | |
152 T (1, "%.*d", R ( 0, 1), 0); /* { dg-warning "may write a terminating nul" } */ | |
153 T (1, "%.*d", R ( 0, 2), 0); /* { dg-warning "directive writing up to 2 bytes" } */ | |
154 T (1, "%.*d", R ( 0, INT_MAX - 1), 0); /* { dg-warning "directive writing up to \[0-9\]+ bytes" } */ | |
155 T (1, "%.*d", R ( 1, INT_MAX - 1), 0); /* { dg-warning "directive writing between 1 and \[0-9\]+ bytes" } */ | |
156 } | |
157 | |
158 /* { dg-prune-output "flag used with .%.. gnu_printf format" } */ |