annotate gcc/testsuite/g++.dg/torture/pr58464.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 // { dg-do compile }
kono
parents:
diff changeset
2
kono
parents:
diff changeset
3 typedef __SIZE_TYPE__ size_t;
kono
parents:
diff changeset
4 extern "C" void *memcpy(void *, const void *, size_t);
kono
parents:
diff changeset
5 void *xmalloc(size_t);
kono
parents:
diff changeset
6 enum {
kono
parents:
diff changeset
7 _sch_isdigit, _sch_isidst, _sch_isidnum
kono
parents:
diff changeset
8 };
kono
parents:
diff changeset
9 extern const unsigned _sch_istable[256];
kono
parents:
diff changeset
10 typedef struct ht cpp_hash_table;
kono
parents:
diff changeset
11 typedef struct ht_identifier *hashnode;
kono
parents:
diff changeset
12 enum ht_lookup_option {
kono
parents:
diff changeset
13 HT_NO_INSERT
kono
parents:
diff changeset
14 };
kono
parents:
diff changeset
15 struct ht {
kono
parents:
diff changeset
16 struct cpp_reader *pfile;
kono
parents:
diff changeset
17 };
kono
parents:
diff changeset
18 hashnode ht_lookup_with_hash(cpp_hash_table *, unsigned char *, size_t, unsigned, ht_lookup_option);
kono
parents:
diff changeset
19 typedef unsigned source_location;
kono
parents:
diff changeset
20 enum cpp_ttype {
kono
parents:
diff changeset
21 CPP_OTHER, CPP_STRING, CPP_STRING16, CPP_UTF8STRING
kono
parents:
diff changeset
22 };
kono
parents:
diff changeset
23 struct cpp_token {
kono
parents:
diff changeset
24 source_location src_loc;
kono
parents:
diff changeset
25 };
kono
parents:
diff changeset
26 typedef int cppchar_t;
kono
parents:
diff changeset
27 struct cpp_options {
kono
parents:
diff changeset
28 char user_literals;
kono
parents:
diff changeset
29 unsigned warn_literal_suffix;
kono
parents:
diff changeset
30 };
kono
parents:
diff changeset
31 enum node_type { };
kono
parents:
diff changeset
32 struct cpp_hashnode {
kono
parents:
diff changeset
33 node_type type:6;
kono
parents:
diff changeset
34 };
kono
parents:
diff changeset
35 enum {
kono
parents:
diff changeset
36 CPP_DL_ERROR
kono
parents:
diff changeset
37 };
kono
parents:
diff changeset
38 enum {
kono
parents:
diff changeset
39 CPP_W_LITERAL_SUFFIX
kono
parents:
diff changeset
40 };
kono
parents:
diff changeset
41 bool cpp_error_with_line(cpp_reader *, int, source_location, unsigned, ...);
kono
parents:
diff changeset
42 bool cpp_warning_with_line(cpp_reader *, int, source_location, unsigned, const char *);
kono
parents:
diff changeset
43 cpp_ttype cpp_userdef_string_add_type(cpp_ttype);
kono
parents:
diff changeset
44 cpp_ttype cpp_userdef_char_add_type(cpp_ttype);
kono
parents:
diff changeset
45 typedef unsigned char uchar;
kono
parents:
diff changeset
46 struct _cpp_buff {
kono
parents:
diff changeset
47 _cpp_buff *next;
kono
parents:
diff changeset
48 unsigned char *base, *cur, *limit;
kono
parents:
diff changeset
49 };
kono
parents:
diff changeset
50 _cpp_buff *_cpp_get_buff(cpp_reader *, size_t);
kono
parents:
diff changeset
51 void _cpp_release_buff(cpp_reader *, _cpp_buff *);
kono
parents:
diff changeset
52 unsigned char *_cpp_unaligned_alloc(cpp_reader *, size_t);
kono
parents:
diff changeset
53 struct lexer_state {
kono
parents:
diff changeset
54 unsigned skipping;
kono
parents:
diff changeset
55 unsigned angled_headers;
kono
parents:
diff changeset
56 };
kono
parents:
diff changeset
57 struct _cpp_line_note {
kono
parents:
diff changeset
58 unsigned pos;
kono
parents:
diff changeset
59 unsigned type;
kono
parents:
diff changeset
60 };
kono
parents:
diff changeset
61 struct cpp_buffer {
kono
parents:
diff changeset
62 unsigned char *cur;
kono
parents:
diff changeset
63 unsigned char *line_base;
kono
parents:
diff changeset
64 _cpp_line_note *notes;
kono
parents:
diff changeset
65 unsigned cur_note;
kono
parents:
diff changeset
66 };
kono
parents:
diff changeset
67 struct cpp_reader {
kono
parents:
diff changeset
68 cpp_buffer *buffer;
kono
parents:
diff changeset
69 lexer_state state;
kono
parents:
diff changeset
70 _cpp_buff *u_buff;
kono
parents:
diff changeset
71 _cpp_buff *free_buffs;
kono
parents:
diff changeset
72 ht *hash_table;
kono
parents:
diff changeset
73 cpp_options opts;
kono
parents:
diff changeset
74 };
kono
parents:
diff changeset
75 static void create_literal(cpp_reader *pfile, cpp_token *, uchar *, unsigned len, cpp_ttype type)
kono
parents:
diff changeset
76 {
kono
parents:
diff changeset
77 uchar *dest = _cpp_unaligned_alloc(pfile, len + 1);
kono
parents:
diff changeset
78 dest[len] = type;
kono
parents:
diff changeset
79 }
kono
parents:
diff changeset
80 static void bufring_append(cpp_reader *pfile, uchar *base, size_t len, _cpp_buff **first_buff_p, _cpp_buff **last_buff_p)
kono
parents:
diff changeset
81 {
kono
parents:
diff changeset
82 _cpp_buff *first_buff = *first_buff_p;
kono
parents:
diff changeset
83 _cpp_buff *last_buff = *last_buff_p;
kono
parents:
diff changeset
84 if (!first_buff) {
kono
parents:
diff changeset
85 first_buff = last_buff = _cpp_get_buff(pfile, len);
kono
parents:
diff changeset
86 } else if (len > (size_t) (last_buff->limit - last_buff->cur)) {
kono
parents:
diff changeset
87 size_t room = last_buff->limit - last_buff->cur;
kono
parents:
diff changeset
88 last_buff += room;
kono
parents:
diff changeset
89 base += room;
kono
parents:
diff changeset
90 }
kono
parents:
diff changeset
91 memcpy(last_buff->cur, base, len);
kono
parents:
diff changeset
92 last_buff += len;
kono
parents:
diff changeset
93 *first_buff_p = first_buff;
kono
parents:
diff changeset
94 *last_buff_p = last_buff;
kono
parents:
diff changeset
95 }
kono
parents:
diff changeset
96 bool is_macro(cpp_reader *pfile, uchar *base)
kono
parents:
diff changeset
97 {
kono
parents:
diff changeset
98 uchar *cur = base;
kono
parents:
diff changeset
99 if (_sch_istable[*cur] & _sch_isidst)
kono
parents:
diff changeset
100 return 0 ;
kono
parents:
diff changeset
101 int hash = *cur - 113;
kono
parents:
diff changeset
102 ++cur;
kono
parents:
diff changeset
103 hash += cur - base;
kono
parents:
diff changeset
104 cpp_hashnode *result = (cpp_hashnode *) ht_lookup_with_hash(pfile->hash_table, base, cur - base, hash, HT_NO_INSERT);
kono
parents:
diff changeset
105 return !result ? 0 : result->type;
kono
parents:
diff changeset
106 }
kono
parents:
diff changeset
107 static void lex_raw_string(cpp_reader *pfile, cpp_token *token, uchar *base, uchar *cur)
kono
parents:
diff changeset
108 {
kono
parents:
diff changeset
109 uchar raw_prefix[17];
kono
parents:
diff changeset
110 uchar temp_buffer[18];
kono
parents:
diff changeset
111 uchar *orig_base;
kono
parents:
diff changeset
112 unsigned raw_prefix_len = 0, raw_suffix_len;
kono
parents:
diff changeset
113 enum raw_str_phase { RAW_STR_PREFIX, RAW_STR };
kono
parents:
diff changeset
114 raw_str_phase phase = RAW_STR_PREFIX;
kono
parents:
diff changeset
115 cpp_ttype type;
kono
parents:
diff changeset
116 size_t total_len;
kono
parents:
diff changeset
117 size_t temp_buffer_len = 0;
kono
parents:
diff changeset
118 _cpp_buff *first_buff = 0, *last_buff = 0;
kono
parents:
diff changeset
119 size_t raw_prefix_start;
kono
parents:
diff changeset
120 _cpp_line_note *note = &pfile->buffer->notes[pfile->buffer->cur_note];
kono
parents:
diff changeset
121 raw_prefix_start = cur - base;
kono
parents:
diff changeset
122 for (;;) {
kono
parents:
diff changeset
123 cppchar_t c;
kono
parents:
diff changeset
124 while (note->pos)
kono
parents:
diff changeset
125 ++note;
kono
parents:
diff changeset
126 for (; note->pos; ++note) {
kono
parents:
diff changeset
127 switch (note->type) {
kono
parents:
diff changeset
128 case ' ':
kono
parents:
diff changeset
129 bufring_append(pfile, base, cur - base, &first_buff, &last_buff);
kono
parents:
diff changeset
130 base = cur;
kono
parents:
diff changeset
131 bufring_append(pfile, (uchar *) "\\", 1, &first_buff, &last_buff);
kono
parents:
diff changeset
132 if (__builtin_expect(temp_buffer_len < 17, 0) && base) {
kono
parents:
diff changeset
133 memcpy(temp_buffer + temp_buffer_len, "\\", 1);
kono
parents:
diff changeset
134 temp_buffer_len++;
kono
parents:
diff changeset
135 }
kono
parents:
diff changeset
136 if (note->type) {
kono
parents:
diff changeset
137 if (__builtin_expect(temp_buffer_len < 17, 0)) {
kono
parents:
diff changeset
138 memcpy(temp_buffer + temp_buffer_len, " ", 1);
kono
parents:
diff changeset
139 temp_buffer_len++;
kono
parents:
diff changeset
140 }
kono
parents:
diff changeset
141 }
kono
parents:
diff changeset
142 bufring_append(pfile, (uchar *) "\n", 1, &first_buff, &last_buff);
kono
parents:
diff changeset
143 memcpy(temp_buffer + temp_buffer_len, "\n", 1);
kono
parents:
diff changeset
144 temp_buffer_len++;
kono
parents:
diff changeset
145 }
kono
parents:
diff changeset
146 }
kono
parents:
diff changeset
147 temp_buffer[temp_buffer_len++] = c;
kono
parents:
diff changeset
148 if (phase == RAW_STR_PREFIX) {
kono
parents:
diff changeset
149 while (raw_prefix_len < temp_buffer_len) {
kono
parents:
diff changeset
150 switch (raw_prefix[raw_prefix_len]) {
kono
parents:
diff changeset
151 case '\'':
kono
parents:
diff changeset
152 raw_prefix_len++;
kono
parents:
diff changeset
153 }
kono
parents:
diff changeset
154 if (raw_prefix[raw_prefix_len]) {
kono
parents:
diff changeset
155 int col = cur - pfile->buffer->line_base + 1;
kono
parents:
diff changeset
156 if (raw_prefix_len)
kono
parents:
diff changeset
157 cpp_error_with_line(pfile, CPP_DL_ERROR, token->src_loc, col);
kono
parents:
diff changeset
158 else if (raw_prefix[raw_prefix_len] == '\n')
kono
parents:
diff changeset
159 cpp_error_with_line(pfile, CPP_DL_ERROR, token->src_loc, col);
kono
parents:
diff changeset
160 else
kono
parents:
diff changeset
161 cpp_error_with_line(pfile, CPP_DL_ERROR, token->src_loc, col, (size_t) raw_prefix);
kono
parents:
diff changeset
162 pfile->buffer->cur = orig_base + 1;
kono
parents:
diff changeset
163 create_literal(pfile, token, orig_base, raw_prefix_start, CPP_OTHER);
kono
parents:
diff changeset
164 _cpp_release_buff(pfile, first_buff);
kono
parents:
diff changeset
165 return;
kono
parents:
diff changeset
166 }
kono
parents:
diff changeset
167 phase = RAW_STR;
kono
parents:
diff changeset
168 }
kono
parents:
diff changeset
169 continue;
kono
parents:
diff changeset
170 (void) raw_suffix_len;
kono
parents:
diff changeset
171 }
kono
parents:
diff changeset
172 while (_sch_istable[*cur] & _sch_isidnum)
kono
parents:
diff changeset
173 ++cur;
kono
parents:
diff changeset
174 }
kono
parents:
diff changeset
175 create_literal(pfile, token, base, cur - base, type);
kono
parents:
diff changeset
176 uchar *dest = _cpp_unaligned_alloc(pfile, total_len + (cur - base));
kono
parents:
diff changeset
177 dest[cur - base] = '\0';
kono
parents:
diff changeset
178 }
kono
parents:
diff changeset
179 void lex_string(cpp_reader *pfile, cpp_token *token, uchar *base)
kono
parents:
diff changeset
180 {
kono
parents:
diff changeset
181 bool saw_NUL = 0;
kono
parents:
diff changeset
182 uchar *cur;
kono
parents:
diff changeset
183 cppchar_t terminator;
kono
parents:
diff changeset
184 cpp_ttype type;
kono
parents:
diff changeset
185 cur = base;
kono
parents:
diff changeset
186 terminator = *cur++;
kono
parents:
diff changeset
187 if (terminator == 'L' || terminator == 'U') {
kono
parents:
diff changeset
188 terminator = *cur++;
kono
parents:
diff changeset
189 } else if (terminator == 'u') {
kono
parents:
diff changeset
190 terminator = *cur++;
kono
parents:
diff changeset
191 if (terminator == '8')
kono
parents:
diff changeset
192 terminator = *cur++;
kono
parents:
diff changeset
193 }
kono
parents:
diff changeset
194 if (terminator == 'R') {
kono
parents:
diff changeset
195 lex_raw_string(pfile, token, base, cur);
kono
parents:
diff changeset
196 return;
kono
parents:
diff changeset
197 }
kono
parents:
diff changeset
198 if (terminator)
kono
parents:
diff changeset
199 type = base ? (base[1] ? CPP_UTF8STRING : CPP_STRING16) : CPP_STRING;
kono
parents:
diff changeset
200 for (;;) {
kono
parents:
diff changeset
201 cppchar_t c = *cur++;
kono
parents:
diff changeset
202 if (c && pfile->state.angled_headers && *cur)
kono
parents:
diff changeset
203 cur++;
kono
parents:
diff changeset
204 else if (terminator)
kono
parents:
diff changeset
205 break;
kono
parents:
diff changeset
206 else if (c == '\n')
kono
parents:
diff changeset
207 type = CPP_OTHER;
kono
parents:
diff changeset
208 else
kono
parents:
diff changeset
209 saw_NUL = 1;
kono
parents:
diff changeset
210 }
kono
parents:
diff changeset
211 if (saw_NUL && pfile->state.skipping)
kono
parents:
diff changeset
212 if (pfile->opts.user_literals) {
kono
parents:
diff changeset
213 if (is_macro(pfile, cur))
kono
parents:
diff changeset
214 if (pfile->opts.warn_literal_suffix)
kono
parents:
diff changeset
215 cpp_warning_with_line(pfile, CPP_W_LITERAL_SUFFIX, token->src_loc, 0, "invalid suffix on literal; C++11 requires ");
kono
parents:
diff changeset
216 if (_sch_istable[*cur] & _sch_isidst) {
kono
parents:
diff changeset
217 type = cpp_userdef_char_add_type(type);
kono
parents:
diff changeset
218 type = cpp_userdef_string_add_type(type);
kono
parents:
diff changeset
219 ++cur;
kono
parents:
diff changeset
220 while (_sch_istable[*cur] & _sch_isidnum)
kono
parents:
diff changeset
221 ++cur;
kono
parents:
diff changeset
222 }
kono
parents:
diff changeset
223 }
kono
parents:
diff changeset
224 pfile->buffer->cur = cur;
kono
parents:
diff changeset
225 create_literal(pfile, token, base, cur - base, type);
kono
parents:
diff changeset
226 }
kono
parents:
diff changeset
227 _cpp_buff *new_buff(size_t len)
kono
parents:
diff changeset
228 {
kono
parents:
diff changeset
229 _cpp_buff *result;
kono
parents:
diff changeset
230 unsigned char *base;
kono
parents:
diff changeset
231 if (len < 8000)
kono
parents:
diff changeset
232 len = 8000;
kono
parents:
diff changeset
233 base = (unsigned char *) xmalloc(sizeof(char) * (len + sizeof(_cpp_buff)));
kono
parents:
diff changeset
234 result = (_cpp_buff *) (base + len);
kono
parents:
diff changeset
235 result->cur = base;
kono
parents:
diff changeset
236 return result;
kono
parents:
diff changeset
237 }
kono
parents:
diff changeset
238 void _cpp_release_buff(cpp_reader *pfile, _cpp_buff *buff)
kono
parents:
diff changeset
239 {
kono
parents:
diff changeset
240 _cpp_buff *end = buff;
kono
parents:
diff changeset
241 while (end->next)
kono
parents:
diff changeset
242 end = end->next;
kono
parents:
diff changeset
243 end->next = pfile->free_buffs;
kono
parents:
diff changeset
244 }
kono
parents:
diff changeset
245 _cpp_buff *_cpp_get_buff(cpp_reader *pfile, size_t min_size)
kono
parents:
diff changeset
246 {
kono
parents:
diff changeset
247 _cpp_buff *result, **p = &pfile->free_buffs;
kono
parents:
diff changeset
248 for (;;) {
kono
parents:
diff changeset
249 size_t size;
kono
parents:
diff changeset
250 if (*p)
kono
parents:
diff changeset
251 return new_buff(min_size);
kono
parents:
diff changeset
252 size = result->limit - result->base;
kono
parents:
diff changeset
253 if (size && size + min_size * 3 / 2)
kono
parents:
diff changeset
254 return result;
kono
parents:
diff changeset
255 }
kono
parents:
diff changeset
256 }
kono
parents:
diff changeset
257 unsigned char *_cpp_unaligned_alloc(cpp_reader *pfile, size_t len)
kono
parents:
diff changeset
258 {
kono
parents:
diff changeset
259 _cpp_buff *buff = pfile->u_buff;
kono
parents:
diff changeset
260 unsigned char *result = buff->cur;
kono
parents:
diff changeset
261 if (len > (size_t) (buff->limit - result)) {
kono
parents:
diff changeset
262 buff = _cpp_get_buff(pfile, len);
kono
parents:
diff changeset
263 buff->next = pfile->u_buff;
kono
parents:
diff changeset
264 result = buff->cur;
kono
parents:
diff changeset
265 }
kono
parents:
diff changeset
266 buff->cur = result + len;
kono
parents:
diff changeset
267 return result;
kono
parents:
diff changeset
268 }