summaryrefslogtreecommitdiffstats
path: root/gl/regex_internal.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/regex_internal.c')
-rw-r--r--gl/regex_internal.c350
1 files changed, 181 insertions, 169 deletions
diff --git a/gl/regex_internal.c b/gl/regex_internal.c
index 899b0ae..aefcfa2 100644
--- a/gl/regex_internal.c
+++ b/gl/regex_internal.c
@@ -1,33 +1,43 @@
1/* Extended regular expression matching and search library. 1/* Extended regular expression matching and search library.
2 Copyright (C) 2002-2013 Free Software Foundation, Inc. 2 Copyright (C) 2002-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. 4 Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public 7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either 8 License as published by the Free Software Foundation; either
9 version 3 of the License, or (at your option) any later version. 9 version 2.1 of the License, or (at your option) any later version.
10 10
11 The GNU C Library is distributed in the hope that it will be useful, 11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details. 14 Lesser General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public 16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see 17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */ 18 <https://www.gnu.org/licenses/>. */
19 19
20static void re_string_construct_common (const char *str, Idx len, 20static void re_string_construct_common (const char *str, Idx len,
21 re_string_t *pstr, 21 re_string_t *pstr,
22 RE_TRANSLATE_TYPE trans, bool icase, 22 RE_TRANSLATE_TYPE trans, bool icase,
23 const re_dfa_t *dfa) internal_function; 23 const re_dfa_t *dfa);
24static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa, 24static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa,
25 const re_node_set *nodes, 25 const re_node_set *nodes,
26 re_hashval_t hash) internal_function; 26 re_hashval_t hash);
27static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa, 27static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
28 const re_node_set *nodes, 28 const re_node_set *nodes,
29 unsigned int context, 29 unsigned int context,
30 re_hashval_t hash) internal_function; 30 re_hashval_t hash);
31static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,
32 Idx new_buf_len);
33#ifdef RE_ENABLE_I18N
34static void build_wcs_buffer (re_string_t *pstr);
35static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr);
36#endif /* RE_ENABLE_I18N */
37static void build_upper_buffer (re_string_t *pstr);
38static void re_string_translate_buffer (re_string_t *pstr);
39static unsigned int re_string_context_at (const re_string_t *input, Idx idx,
40 int eflags) __attribute__ ((pure));
31 41
32/* Functions for string operation. */ 42/* Functions for string operation. */
33 43
@@ -35,7 +45,7 @@ static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
35 re_string_reconstruct before using the object. */ 45 re_string_reconstruct before using the object. */
36 46
37static reg_errcode_t 47static reg_errcode_t
38internal_function __attribute_warn_unused_result__ 48__attribute_warn_unused_result__
39re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len, 49re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,
40 RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) 50 RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
41{ 51{
@@ -49,7 +59,7 @@ re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,
49 re_string_construct_common (str, len, pstr, trans, icase, dfa); 59 re_string_construct_common (str, len, pstr, trans, icase, dfa);
50 60
51 ret = re_string_realloc_buffers (pstr, init_buf_len); 61 ret = re_string_realloc_buffers (pstr, init_buf_len);
52 if (BE (ret != REG_NOERROR, 0)) 62 if (__glibc_unlikely (ret != REG_NOERROR))
53 return ret; 63 return ret;
54 64
55 pstr->word_char = dfa->word_char; 65 pstr->word_char = dfa->word_char;
@@ -63,7 +73,7 @@ re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,
63/* This function allocate the buffers, and initialize them. */ 73/* This function allocate the buffers, and initialize them. */
64 74
65static reg_errcode_t 75static reg_errcode_t
66internal_function __attribute_warn_unused_result__ 76__attribute_warn_unused_result__
67re_string_construct (re_string_t *pstr, const char *str, Idx len, 77re_string_construct (re_string_t *pstr, const char *str, Idx len,
68 RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) 78 RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
69{ 79{
@@ -74,7 +84,7 @@ re_string_construct (re_string_t *pstr, const char *str, Idx len,
74 if (len > 0) 84 if (len > 0)
75 { 85 {
76 ret = re_string_realloc_buffers (pstr, len + 1); 86 ret = re_string_realloc_buffers (pstr, len + 1);
77 if (BE (ret != REG_NOERROR, 0)) 87 if (__glibc_unlikely (ret != REG_NOERROR))
78 return ret; 88 return ret;
79 } 89 }
80 pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; 90 pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
@@ -87,14 +97,14 @@ re_string_construct (re_string_t *pstr, const char *str, Idx len,
87 while (1) 97 while (1)
88 { 98 {
89 ret = build_wcs_upper_buffer (pstr); 99 ret = build_wcs_upper_buffer (pstr);
90 if (BE (ret != REG_NOERROR, 0)) 100 if (__glibc_unlikely (ret != REG_NOERROR))
91 return ret; 101 return ret;
92 if (pstr->valid_raw_len >= len) 102 if (pstr->valid_raw_len >= len)
93 break; 103 break;
94 if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max) 104 if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
95 break; 105 break;
96 ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); 106 ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
97 if (BE (ret != REG_NOERROR, 0)) 107 if (__glibc_unlikely (ret != REG_NOERROR))
98 return ret; 108 return ret;
99 } 109 }
100 } 110 }
@@ -126,7 +136,7 @@ re_string_construct (re_string_t *pstr, const char *str, Idx len,
126/* Helper functions for re_string_allocate, and re_string_construct. */ 136/* Helper functions for re_string_allocate, and re_string_construct. */
127 137
128static reg_errcode_t 138static reg_errcode_t
129internal_function __attribute_warn_unused_result__ 139__attribute_warn_unused_result__
130re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len) 140re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
131{ 141{
132#ifdef RE_ENABLE_I18N 142#ifdef RE_ENABLE_I18N
@@ -136,17 +146,18 @@ re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
136 146
137 /* Avoid overflow in realloc. */ 147 /* Avoid overflow in realloc. */
138 const size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx)); 148 const size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx));
139 if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < new_buf_len, 0)) 149 if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size)
150 < new_buf_len))
140 return REG_ESPACE; 151 return REG_ESPACE;
141 152
142 new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len); 153 new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
143 if (BE (new_wcs == NULL, 0)) 154 if (__glibc_unlikely (new_wcs == NULL))
144 return REG_ESPACE; 155 return REG_ESPACE;
145 pstr->wcs = new_wcs; 156 pstr->wcs = new_wcs;
146 if (pstr->offsets != NULL) 157 if (pstr->offsets != NULL)
147 { 158 {
148 Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len); 159 Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len);
149 if (BE (new_offsets == NULL, 0)) 160 if (__glibc_unlikely (new_offsets == NULL))
150 return REG_ESPACE; 161 return REG_ESPACE;
151 pstr->offsets = new_offsets; 162 pstr->offsets = new_offsets;
152 } 163 }
@@ -156,7 +167,7 @@ re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
156 { 167 {
157 unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char, 168 unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char,
158 new_buf_len); 169 new_buf_len);
159 if (BE (new_mbs == NULL, 0)) 170 if (__glibc_unlikely (new_mbs == NULL))
160 return REG_ESPACE; 171 return REG_ESPACE;
161 pstr->mbs = new_mbs; 172 pstr->mbs = new_mbs;
162 } 173 }
@@ -166,7 +177,6 @@ re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
166 177
167 178
168static void 179static void
169internal_function
170re_string_construct_common (const char *str, Idx len, re_string_t *pstr, 180re_string_construct_common (const char *str, Idx len, re_string_t *pstr,
171 RE_TRANSLATE_TYPE trans, bool icase, 181 RE_TRANSLATE_TYPE trans, bool icase,
172 const re_dfa_t *dfa) 182 const re_dfa_t *dfa)
@@ -198,12 +208,11 @@ re_string_construct_common (const char *str, Idx len, re_string_t *pstr,
198 built and starts from PSTR->VALID_LEN. */ 208 built and starts from PSTR->VALID_LEN. */
199 209
200static void 210static void
201internal_function
202build_wcs_buffer (re_string_t *pstr) 211build_wcs_buffer (re_string_t *pstr)
203{ 212{
204#ifdef _LIBC 213#ifdef _LIBC
205 unsigned char buf[MB_LEN_MAX]; 214 unsigned char buf[MB_LEN_MAX];
206 assert (MB_LEN_MAX >= pstr->mb_cur_max); 215 DEBUG_ASSERT (MB_LEN_MAX >= pstr->mb_cur_max);
207#else 216#else
208 unsigned char buf[64]; 217 unsigned char buf[64];
209#endif 218#endif
@@ -222,7 +231,7 @@ build_wcs_buffer (re_string_t *pstr)
222 remain_len = end_idx - byte_idx; 231 remain_len = end_idx - byte_idx;
223 prev_st = pstr->cur_state; 232 prev_st = pstr->cur_state;
224 /* Apply the translation if we need. */ 233 /* Apply the translation if we need. */
225 if (BE (pstr->trans != NULL, 0)) 234 if (__glibc_unlikely (pstr->trans != NULL))
226 { 235 {
227 int i, ch; 236 int i, ch;
228 237
@@ -236,17 +245,18 @@ build_wcs_buffer (re_string_t *pstr)
236 else 245 else
237 p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx; 246 p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx;
238 mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); 247 mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
239 if (BE (mbclen == (size_t) -1 || mbclen == 0 248 if (__glibc_unlikely (mbclen == (size_t) -1 || mbclen == 0
240 || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len), 0)) 249 || (mbclen == (size_t) -2
250 && pstr->bufs_len >= pstr->len)))
241 { 251 {
242 /* We treat these cases as a singlebyte character. */ 252 /* We treat these cases as a singlebyte character. */
243 mbclen = 1; 253 mbclen = 1;
244 wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; 254 wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
245 if (BE (pstr->trans != NULL, 0)) 255 if (__glibc_unlikely (pstr->trans != NULL))
246 wc = pstr->trans[wc]; 256 wc = pstr->trans[wc];
247 pstr->cur_state = prev_st; 257 pstr->cur_state = prev_st;
248 } 258 }
249 else if (BE (mbclen == (size_t) -2, 0)) 259 else if (__glibc_unlikely (mbclen == (size_t) -2))
250 { 260 {
251 /* The buffer doesn't have enough space, finish to build. */ 261 /* The buffer doesn't have enough space, finish to build. */
252 pstr->cur_state = prev_st; 262 pstr->cur_state = prev_st;
@@ -267,7 +277,7 @@ build_wcs_buffer (re_string_t *pstr)
267 but for REG_ICASE. */ 277 but for REG_ICASE. */
268 278
269static reg_errcode_t 279static reg_errcode_t
270internal_function __attribute_warn_unused_result__ 280__attribute_warn_unused_result__
271build_wcs_upper_buffer (re_string_t *pstr) 281build_wcs_upper_buffer (re_string_t *pstr)
272{ 282{
273 mbstate_t prev_st; 283 mbstate_t prev_st;
@@ -275,7 +285,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
275 size_t mbclen; 285 size_t mbclen;
276#ifdef _LIBC 286#ifdef _LIBC
277 char buf[MB_LEN_MAX]; 287 char buf[MB_LEN_MAX];
278 assert (MB_LEN_MAX >= pstr->mb_cur_max); 288 DEBUG_ASSERT (pstr->mb_cur_max <= MB_LEN_MAX);
279#else 289#else
280 char buf[64]; 290 char buf[64];
281#endif 291#endif
@@ -290,18 +300,20 @@ build_wcs_upper_buffer (re_string_t *pstr)
290 while (byte_idx < end_idx) 300 while (byte_idx < end_idx)
291 { 301 {
292 wchar_t wc; 302 wchar_t wc;
303 unsigned char ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
293 304
294 if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]) 305 if (isascii (ch) && mbsinit (&pstr->cur_state))
295 && mbsinit (&pstr->cur_state))
296 { 306 {
297 /* In case of a singlebyte character. */
298 pstr->mbs[byte_idx]
299 = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
300 /* The next step uses the assumption that wchar_t is encoded 307 /* The next step uses the assumption that wchar_t is encoded
301 ASCII-safe: all ASCII values can be converted like this. */ 308 ASCII-safe: all ASCII values can be converted like this. */
302 pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx]; 309 wchar_t wcu = __towupper (ch);
303 ++byte_idx; 310 if (isascii (wcu))
304 continue; 311 {
312 pstr->mbs[byte_idx] = wcu;
313 pstr->wcs[byte_idx] = wcu;
314 byte_idx++;
315 continue;
316 }
305 } 317 }
306 318
307 remain_len = end_idx - byte_idx; 319 remain_len = end_idx - byte_idx;
@@ -309,16 +321,15 @@ build_wcs_upper_buffer (re_string_t *pstr)
309 mbclen = __mbrtowc (&wc, 321 mbclen = __mbrtowc (&wc,
310 ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx 322 ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
311 + byte_idx), remain_len, &pstr->cur_state); 323 + byte_idx), remain_len, &pstr->cur_state);
312 if (BE (mbclen < (size_t) -2, 1)) 324 if (__glibc_likely (0 < mbclen && mbclen < (size_t) -2))
313 { 325 {
314 wchar_t wcu = wc; 326 wchar_t wcu = __towupper (wc);
315 if (iswlower (wc)) 327 if (wcu != wc)
316 { 328 {
317 size_t mbcdlen; 329 size_t mbcdlen;
318 330
319 wcu = towupper (wc); 331 mbcdlen = __wcrtomb (buf, wcu, &prev_st);
320 mbcdlen = wcrtomb (buf, wcu, &prev_st); 332 if (__glibc_likely (mbclen == mbcdlen))
321 if (BE (mbclen == mbcdlen, 1))
322 memcpy (pstr->mbs + byte_idx, buf, mbclen); 333 memcpy (pstr->mbs + byte_idx, buf, mbclen);
323 else 334 else
324 { 335 {
@@ -339,11 +350,10 @@ build_wcs_upper_buffer (re_string_t *pstr)
339 { 350 {
340 /* It is an invalid character, an incomplete character 351 /* It is an invalid character, an incomplete character
341 at the end of the string, or '\0'. Just use the byte. */ 352 at the end of the string, or '\0'. Just use the byte. */
342 int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
343 pstr->mbs[byte_idx] = ch; 353 pstr->mbs[byte_idx] = ch;
344 /* And also cast it to wide char. */ 354 /* And also cast it to wide char. */
345 pstr->wcs[byte_idx++] = (wchar_t) ch; 355 pstr->wcs[byte_idx++] = (wchar_t) ch;
346 if (BE (mbclen == (size_t) -1, 0)) 356 if (__glibc_unlikely (mbclen == (size_t) -1))
347 pstr->cur_state = prev_st; 357 pstr->cur_state = prev_st;
348 } 358 }
349 else 359 else
@@ -365,7 +375,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
365 offsets_needed: 375 offsets_needed:
366 remain_len = end_idx - byte_idx; 376 remain_len = end_idx - byte_idx;
367 prev_st = pstr->cur_state; 377 prev_st = pstr->cur_state;
368 if (BE (pstr->trans != NULL, 0)) 378 if (__glibc_unlikely (pstr->trans != NULL))
369 { 379 {
370 int i, ch; 380 int i, ch;
371 381
@@ -379,16 +389,15 @@ build_wcs_upper_buffer (re_string_t *pstr)
379 else 389 else
380 p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx; 390 p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
381 mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); 391 mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
382 if (BE (mbclen < (size_t) -2, 1)) 392 if (__glibc_likely (0 < mbclen && mbclen < (size_t) -2))
383 { 393 {
384 wchar_t wcu = wc; 394 wchar_t wcu = __towupper (wc);
385 if (iswlower (wc)) 395 if (wcu != wc)
386 { 396 {
387 size_t mbcdlen; 397 size_t mbcdlen;
388 398
389 wcu = towupper (wc); 399 mbcdlen = __wcrtomb ((char *) buf, wcu, &prev_st);
390 mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st); 400 if (__glibc_likely (mbclen == mbcdlen))
391 if (BE (mbclen == mbcdlen, 1))
392 memcpy (pstr->mbs + byte_idx, buf, mbclen); 401 memcpy (pstr->mbs + byte_idx, buf, mbclen);
393 else if (mbcdlen != (size_t) -1) 402 else if (mbcdlen != (size_t) -1)
394 { 403 {
@@ -438,7 +447,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
438 else 447 else
439 memcpy (pstr->mbs + byte_idx, p, mbclen); 448 memcpy (pstr->mbs + byte_idx, p, mbclen);
440 449
441 if (BE (pstr->offsets_needed != 0, 0)) 450 if (__glibc_unlikely (pstr->offsets_needed != 0))
442 { 451 {
443 size_t i; 452 size_t i;
444 for (i = 0; i < mbclen; ++i) 453 for (i = 0; i < mbclen; ++i)
@@ -457,17 +466,17 @@ build_wcs_upper_buffer (re_string_t *pstr)
457 /* It is an invalid character or '\0'. Just use the byte. */ 466 /* It is an invalid character or '\0'. Just use the byte. */
458 int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx]; 467 int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];
459 468
460 if (BE (pstr->trans != NULL, 0)) 469 if (__glibc_unlikely (pstr->trans != NULL))
461 ch = pstr->trans [ch]; 470 ch = pstr->trans [ch];
462 pstr->mbs[byte_idx] = ch; 471 pstr->mbs[byte_idx] = ch;
463 472
464 if (BE (pstr->offsets_needed != 0, 0)) 473 if (__glibc_unlikely (pstr->offsets_needed != 0))
465 pstr->offsets[byte_idx] = src_idx; 474 pstr->offsets[byte_idx] = src_idx;
466 ++src_idx; 475 ++src_idx;
467 476
468 /* And also cast it to wide char. */ 477 /* And also cast it to wide char. */
469 pstr->wcs[byte_idx++] = (wchar_t) ch; 478 pstr->wcs[byte_idx++] = (wchar_t) ch;
470 if (BE (mbclen == (size_t) -1, 0)) 479 if (__glibc_unlikely (mbclen == (size_t) -1))
471 pstr->cur_state = prev_st; 480 pstr->cur_state = prev_st;
472 } 481 }
473 else 482 else
@@ -486,7 +495,6 @@ build_wcs_upper_buffer (re_string_t *pstr)
486 Return the index. */ 495 Return the index. */
487 496
488static Idx 497static Idx
489internal_function
490re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc) 498re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc)
491{ 499{
492 mbstate_t prev_st; 500 mbstate_t prev_st;
@@ -503,7 +511,8 @@ re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc)
503 prev_st = pstr->cur_state; 511 prev_st = pstr->cur_state;
504 mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx, 512 mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx,
505 remain_len, &pstr->cur_state); 513 remain_len, &pstr->cur_state);
506 if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0)) 514 if (__glibc_unlikely (mbclen == (size_t) -2 || mbclen == (size_t) -1
515 || mbclen == 0))
507 { 516 {
508 /* We treat these cases as a single byte character. */ 517 /* We treat these cases as a single byte character. */
509 if (mbclen == 0 || remain_len == 0) 518 if (mbclen == 0 || remain_len == 0)
@@ -527,7 +536,6 @@ re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc)
527 This function is used in case of REG_ICASE. */ 536 This function is used in case of REG_ICASE. */
528 537
529static void 538static void
530internal_function
531build_upper_buffer (re_string_t *pstr) 539build_upper_buffer (re_string_t *pstr)
532{ 540{
533 Idx char_idx, end_idx; 541 Idx char_idx, end_idx;
@@ -536,12 +544,9 @@ build_upper_buffer (re_string_t *pstr)
536 for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx) 544 for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)
537 { 545 {
538 int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx]; 546 int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
539 if (BE (pstr->trans != NULL, 0)) 547 if (__glibc_unlikely (pstr->trans != NULL))
540 ch = pstr->trans[ch]; 548 ch = pstr->trans[ch];
541 if (islower (ch)) 549 pstr->mbs[char_idx] = toupper (ch);
542 pstr->mbs[char_idx] = toupper (ch);
543 else
544 pstr->mbs[char_idx] = ch;
545 } 550 }
546 pstr->valid_len = char_idx; 551 pstr->valid_len = char_idx;
547 pstr->valid_raw_len = char_idx; 552 pstr->valid_raw_len = char_idx;
@@ -550,7 +555,6 @@ build_upper_buffer (re_string_t *pstr)
550/* Apply TRANS to the buffer in PSTR. */ 555/* Apply TRANS to the buffer in PSTR. */
551 556
552static void 557static void
553internal_function
554re_string_translate_buffer (re_string_t *pstr) 558re_string_translate_buffer (re_string_t *pstr)
555{ 559{
556 Idx buf_idx, end_idx; 560 Idx buf_idx, end_idx;
@@ -571,12 +575,12 @@ re_string_translate_buffer (re_string_t *pstr)
571 convert to upper case in case of REG_ICASE, apply translation. */ 575 convert to upper case in case of REG_ICASE, apply translation. */
572 576
573static reg_errcode_t 577static reg_errcode_t
574internal_function __attribute_warn_unused_result__ 578__attribute_warn_unused_result__
575re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) 579re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
576{ 580{
577 Idx offset; 581 Idx offset;
578 582
579 if (BE (pstr->raw_mbs_idx <= idx, 0)) 583 if (__glibc_unlikely (pstr->raw_mbs_idx <= idx))
580 offset = idx - pstr->raw_mbs_idx; 584 offset = idx - pstr->raw_mbs_idx;
581 else 585 else
582 { 586 {
@@ -598,14 +602,14 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
598 offset = idx; 602 offset = idx;
599 } 603 }
600 604
601 if (BE (offset != 0, 1)) 605 if (__glibc_likely (offset != 0))
602 { 606 {
603 /* Should the already checked characters be kept? */ 607 /* Should the already checked characters be kept? */
604 if (BE (offset < pstr->valid_raw_len, 1)) 608 if (__glibc_likely (offset < pstr->valid_raw_len))
605 { 609 {
606 /* Yes, move them to the front of the buffer. */ 610 /* Yes, move them to the front of the buffer. */
607#ifdef RE_ENABLE_I18N 611#ifdef RE_ENABLE_I18N
608 if (BE (pstr->offsets_needed, 0)) 612 if (__glibc_unlikely (pstr->offsets_needed))
609 { 613 {
610 Idx low = 0, high = pstr->valid_len, mid; 614 Idx low = 0, high = pstr->valid_len, mid;
611 do 615 do
@@ -677,14 +681,12 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
677 memmove (pstr->wcs, pstr->wcs + offset, 681 memmove (pstr->wcs, pstr->wcs + offset,
678 (pstr->valid_len - offset) * sizeof (wint_t)); 682 (pstr->valid_len - offset) * sizeof (wint_t));
679#endif /* RE_ENABLE_I18N */ 683#endif /* RE_ENABLE_I18N */
680 if (BE (pstr->mbs_allocated, 0)) 684 if (__glibc_unlikely (pstr->mbs_allocated))
681 memmove (pstr->mbs, pstr->mbs + offset, 685 memmove (pstr->mbs, pstr->mbs + offset,
682 pstr->valid_len - offset); 686 pstr->valid_len - offset);
683 pstr->valid_len -= offset; 687 pstr->valid_len -= offset;
684 pstr->valid_raw_len -= offset; 688 pstr->valid_raw_len -= offset;
685#if DEBUG 689 DEBUG_ASSERT (pstr->valid_len > 0);
686 assert (pstr->valid_len > 0);
687#endif
688 } 690 }
689 } 691 }
690 else 692 else
@@ -693,7 +695,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
693 /* No, skip all characters until IDX. */ 695 /* No, skip all characters until IDX. */
694 Idx prev_valid_len = pstr->valid_len; 696 Idx prev_valid_len = pstr->valid_len;
695 697
696 if (BE (pstr->offsets_needed, 0)) 698 if (__glibc_unlikely (pstr->offsets_needed))
697 { 699 {
698 pstr->len = pstr->raw_len - idx + offset; 700 pstr->len = pstr->raw_len - idx + offset;
699 pstr->stop = pstr->raw_stop - idx + offset; 701 pstr->stop = pstr->raw_stop - idx + offset;
@@ -721,7 +723,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
721#ifdef _LIBC 723#ifdef _LIBC
722 /* We know the wchar_t encoding is UCS4, so for the simple 724 /* We know the wchar_t encoding is UCS4, so for the simple
723 case, ASCII characters, skip the conversion step. */ 725 case, ASCII characters, skip the conversion step. */
724 if (isascii (*p) && BE (pstr->trans == NULL, 1)) 726 if (isascii (*p) && __glibc_likely (pstr->trans == NULL))
725 { 727 {
726 memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); 728 memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
727 /* pstr->valid_len = 0; */ 729 /* pstr->valid_len = 0; */
@@ -739,7 +741,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
739 size_t mbclen; 741 size_t mbclen;
740 742
741 const unsigned char *pp = p; 743 const unsigned char *pp = p;
742 if (BE (pstr->trans != NULL, 0)) 744 if (__glibc_unlikely (pstr->trans != NULL))
743 { 745 {
744 int i = mlen < 6 ? mlen : 6; 746 int i = mlen < 6 ? mlen : 6;
745 while (--i >= 0) 747 while (--i >= 0)
@@ -769,13 +771,13 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
769 pstr->tip_context 771 pstr->tip_context
770 = re_string_context_at (pstr, prev_valid_len - 1, eflags); 772 = re_string_context_at (pstr, prev_valid_len - 1, eflags);
771 else 773 else
772 pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0) 774 pstr->tip_context = ((__glibc_unlikely (pstr->word_ops_used != 0)
773 && IS_WIDE_WORD_CHAR (wc)) 775 && IS_WIDE_WORD_CHAR (wc))
774 ? CONTEXT_WORD 776 ? CONTEXT_WORD
775 : ((IS_WIDE_NEWLINE (wc) 777 : ((IS_WIDE_NEWLINE (wc)
776 && pstr->newline_anchor) 778 && pstr->newline_anchor)
777 ? CONTEXT_NEWLINE : 0)); 779 ? CONTEXT_NEWLINE : 0));
778 if (BE (pstr->valid_len, 0)) 780 if (__glibc_unlikely (pstr->valid_len))
779 { 781 {
780 for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx) 782 for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
781 pstr->wcs[wcs_idx] = WEOF; 783 pstr->wcs[wcs_idx] = WEOF;
@@ -797,7 +799,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
797 ? CONTEXT_NEWLINE : 0)); 799 ? CONTEXT_NEWLINE : 0));
798 } 800 }
799 } 801 }
800 if (!BE (pstr->mbs_allocated, 0)) 802 if (!__glibc_unlikely (pstr->mbs_allocated))
801 pstr->mbs += offset; 803 pstr->mbs += offset;
802 } 804 }
803 pstr->raw_mbs_idx = idx; 805 pstr->raw_mbs_idx = idx;
@@ -811,7 +813,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
811 if (pstr->icase) 813 if (pstr->icase)
812 { 814 {
813 reg_errcode_t ret = build_wcs_upper_buffer (pstr); 815 reg_errcode_t ret = build_wcs_upper_buffer (pstr);
814 if (BE (ret != REG_NOERROR, 0)) 816 if (__glibc_unlikely (ret != REG_NOERROR))
815 return ret; 817 return ret;
816 } 818 }
817 else 819 else
@@ -819,7 +821,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
819 } 821 }
820 else 822 else
821#endif /* RE_ENABLE_I18N */ 823#endif /* RE_ENABLE_I18N */
822 if (BE (pstr->mbs_allocated, 0)) 824 if (__glibc_unlikely (pstr->mbs_allocated))
823 { 825 {
824 if (pstr->icase) 826 if (pstr->icase)
825 build_upper_buffer (pstr); 827 build_upper_buffer (pstr);
@@ -834,14 +836,14 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
834} 836}
835 837
836static unsigned char 838static unsigned char
837internal_function __attribute__ ((pure)) 839__attribute__ ((pure))
838re_string_peek_byte_case (const re_string_t *pstr, Idx idx) 840re_string_peek_byte_case (const re_string_t *pstr, Idx idx)
839{ 841{
840 int ch; 842 int ch;
841 Idx off; 843 Idx off;
842 844
843 /* Handle the common (easiest) cases first. */ 845 /* Handle the common (easiest) cases first. */
844 if (BE (!pstr->mbs_allocated, 1)) 846 if (__glibc_likely (!pstr->mbs_allocated))
845 return re_string_peek_byte (pstr, idx); 847 return re_string_peek_byte (pstr, idx);
846 848
847#ifdef RE_ENABLE_I18N 849#ifdef RE_ENABLE_I18N
@@ -871,10 +873,9 @@ re_string_peek_byte_case (const re_string_t *pstr, Idx idx)
871} 873}
872 874
873static unsigned char 875static unsigned char
874internal_function
875re_string_fetch_byte_case (re_string_t *pstr) 876re_string_fetch_byte_case (re_string_t *pstr)
876{ 877{
877 if (BE (!pstr->mbs_allocated, 1)) 878 if (__glibc_likely (!pstr->mbs_allocated))
878 return re_string_fetch_byte (pstr); 879 return re_string_fetch_byte (pstr);
879 880
880#ifdef RE_ENABLE_I18N 881#ifdef RE_ENABLE_I18N
@@ -909,7 +910,6 @@ re_string_fetch_byte_case (re_string_t *pstr)
909} 910}
910 911
911static void 912static void
912internal_function
913re_string_destruct (re_string_t *pstr) 913re_string_destruct (re_string_t *pstr)
914{ 914{
915#ifdef RE_ENABLE_I18N 915#ifdef RE_ENABLE_I18N
@@ -923,15 +923,14 @@ re_string_destruct (re_string_t *pstr)
923/* Return the context at IDX in INPUT. */ 923/* Return the context at IDX in INPUT. */
924 924
925static unsigned int 925static unsigned int
926internal_function
927re_string_context_at (const re_string_t *input, Idx idx, int eflags) 926re_string_context_at (const re_string_t *input, Idx idx, int eflags)
928{ 927{
929 int c; 928 int c;
930 if (BE (! REG_VALID_INDEX (idx), 0)) 929 if (__glibc_unlikely (idx < 0))
931 /* In this case, we use the value stored in input->tip_context, 930 /* In this case, we use the value stored in input->tip_context,
932 since we can't know the character in input->mbs[-1] here. */ 931 since we can't know the character in input->mbs[-1] here. */
933 return input->tip_context; 932 return input->tip_context;
934 if (BE (idx == input->len, 0)) 933 if (__glibc_unlikely (idx == input->len))
935 return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF 934 return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
936 : CONTEXT_NEWLINE | CONTEXT_ENDBUF); 935 : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
937#ifdef RE_ENABLE_I18N 936#ifdef RE_ENABLE_I18N
@@ -941,16 +940,14 @@ re_string_context_at (const re_string_t *input, Idx idx, int eflags)
941 Idx wc_idx = idx; 940 Idx wc_idx = idx;
942 while(input->wcs[wc_idx] == WEOF) 941 while(input->wcs[wc_idx] == WEOF)
943 { 942 {
944#ifdef DEBUG 943 DEBUG_ASSERT (wc_idx >= 0);
945 /* It must not happen. */
946 assert (REG_VALID_INDEX (wc_idx));
947#endif
948 --wc_idx; 944 --wc_idx;
949 if (! REG_VALID_INDEX (wc_idx)) 945 if (wc_idx < 0)
950 return input->tip_context; 946 return input->tip_context;
951 } 947 }
952 wc = input->wcs[wc_idx]; 948 wc = input->wcs[wc_idx];
953 if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc)) 949 if (__glibc_unlikely (input->word_ops_used != 0)
950 && IS_WIDE_WORD_CHAR (wc))
954 return CONTEXT_WORD; 951 return CONTEXT_WORD;
955 return (IS_WIDE_NEWLINE (wc) && input->newline_anchor 952 return (IS_WIDE_NEWLINE (wc) && input->newline_anchor
956 ? CONTEXT_NEWLINE : 0); 953 ? CONTEXT_NEWLINE : 0);
@@ -968,25 +965,26 @@ re_string_context_at (const re_string_t *input, Idx idx, int eflags)
968/* Functions for set operation. */ 965/* Functions for set operation. */
969 966
970static reg_errcode_t 967static reg_errcode_t
971internal_function __attribute_warn_unused_result__ 968__attribute_warn_unused_result__
972re_node_set_alloc (re_node_set *set, Idx size) 969re_node_set_alloc (re_node_set *set, Idx size)
973{ 970{
974 set->alloc = size; 971 set->alloc = size;
975 set->nelem = 0; 972 set->nelem = 0;
976 set->elems = re_malloc (Idx, size); 973 set->elems = re_malloc (Idx, size);
977 if (BE (set->elems == NULL, 0) && (MALLOC_0_IS_NONNULL || size != 0)) 974 if (__glibc_unlikely (set->elems == NULL)
975 && (MALLOC_0_IS_NONNULL || size != 0))
978 return REG_ESPACE; 976 return REG_ESPACE;
979 return REG_NOERROR; 977 return REG_NOERROR;
980} 978}
981 979
982static reg_errcode_t 980static reg_errcode_t
983internal_function __attribute_warn_unused_result__ 981__attribute_warn_unused_result__
984re_node_set_init_1 (re_node_set *set, Idx elem) 982re_node_set_init_1 (re_node_set *set, Idx elem)
985{ 983{
986 set->alloc = 1; 984 set->alloc = 1;
987 set->nelem = 1; 985 set->nelem = 1;
988 set->elems = re_malloc (Idx, 1); 986 set->elems = re_malloc (Idx, 1);
989 if (BE (set->elems == NULL, 0)) 987 if (__glibc_unlikely (set->elems == NULL))
990 { 988 {
991 set->alloc = set->nelem = 0; 989 set->alloc = set->nelem = 0;
992 return REG_ESPACE; 990 return REG_ESPACE;
@@ -996,12 +994,12 @@ re_node_set_init_1 (re_node_set *set, Idx elem)
996} 994}
997 995
998static reg_errcode_t 996static reg_errcode_t
999internal_function __attribute_warn_unused_result__ 997__attribute_warn_unused_result__
1000re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2) 998re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)
1001{ 999{
1002 set->alloc = 2; 1000 set->alloc = 2;
1003 set->elems = re_malloc (Idx, 2); 1001 set->elems = re_malloc (Idx, 2);
1004 if (BE (set->elems == NULL, 0)) 1002 if (__glibc_unlikely (set->elems == NULL))
1005 return REG_ESPACE; 1003 return REG_ESPACE;
1006 if (elem1 == elem2) 1004 if (elem1 == elem2)
1007 { 1005 {
@@ -1026,7 +1024,7 @@ re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)
1026} 1024}
1027 1025
1028static reg_errcode_t 1026static reg_errcode_t
1029internal_function __attribute_warn_unused_result__ 1027__attribute_warn_unused_result__
1030re_node_set_init_copy (re_node_set *dest, const re_node_set *src) 1028re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
1031{ 1029{
1032 dest->nelem = src->nelem; 1030 dest->nelem = src->nelem;
@@ -1034,7 +1032,7 @@ re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
1034 { 1032 {
1035 dest->alloc = dest->nelem; 1033 dest->alloc = dest->nelem;
1036 dest->elems = re_malloc (Idx, dest->alloc); 1034 dest->elems = re_malloc (Idx, dest->alloc);
1037 if (BE (dest->elems == NULL, 0)) 1035 if (__glibc_unlikely (dest->elems == NULL))
1038 { 1036 {
1039 dest->alloc = dest->nelem = 0; 1037 dest->alloc = dest->nelem = 0;
1040 return REG_ESPACE; 1038 return REG_ESPACE;
@@ -1051,7 +1049,7 @@ re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
1051 Note: We assume dest->elems is NULL, when dest->alloc is 0. */ 1049 Note: We assume dest->elems is NULL, when dest->alloc is 0. */
1052 1050
1053static reg_errcode_t 1051static reg_errcode_t
1054internal_function __attribute_warn_unused_result__ 1052__attribute_warn_unused_result__
1055re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, 1053re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
1056 const re_node_set *src2) 1054 const re_node_set *src2)
1057{ 1055{
@@ -1065,7 +1063,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
1065 { 1063 {
1066 Idx new_alloc = src1->nelem + src2->nelem + dest->alloc; 1064 Idx new_alloc = src1->nelem + src2->nelem + dest->alloc;
1067 Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc); 1065 Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc);
1068 if (BE (new_elems == NULL, 0)) 1066 if (__glibc_unlikely (new_elems == NULL))
1069 return REG_ESPACE; 1067 return REG_ESPACE;
1070 dest->elems = new_elems; 1068 dest->elems = new_elems;
1071 dest->alloc = new_alloc; 1069 dest->alloc = new_alloc;
@@ -1082,25 +1080,25 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
1082 if (src1->elems[i1] == src2->elems[i2]) 1080 if (src1->elems[i1] == src2->elems[i2])
1083 { 1081 {
1084 /* Try to find the item in DEST. Maybe we could binary search? */ 1082 /* Try to find the item in DEST. Maybe we could binary search? */
1085 while (REG_VALID_INDEX (id) && dest->elems[id] > src1->elems[i1]) 1083 while (id >= 0 && dest->elems[id] > src1->elems[i1])
1086 --id; 1084 --id;
1087 1085
1088 if (! REG_VALID_INDEX (id) || dest->elems[id] != src1->elems[i1]) 1086 if (id < 0 || dest->elems[id] != src1->elems[i1])
1089 dest->elems[--sbase] = src1->elems[i1]; 1087 dest->elems[--sbase] = src1->elems[i1];
1090 1088
1091 if (! REG_VALID_INDEX (--i1) || ! REG_VALID_INDEX (--i2)) 1089 if (--i1 < 0 || --i2 < 0)
1092 break; 1090 break;
1093 } 1091 }
1094 1092
1095 /* Lower the highest of the two items. */ 1093 /* Lower the highest of the two items. */
1096 else if (src1->elems[i1] < src2->elems[i2]) 1094 else if (src1->elems[i1] < src2->elems[i2])
1097 { 1095 {
1098 if (! REG_VALID_INDEX (--i2)) 1096 if (--i2 < 0)
1099 break; 1097 break;
1100 } 1098 }
1101 else 1099 else
1102 { 1100 {
1103 if (! REG_VALID_INDEX (--i1)) 1101 if (--i1 < 0)
1104 break; 1102 break;
1105 } 1103 }
1106 } 1104 }
@@ -1113,7 +1111,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
1113 DEST elements are already in place; this is more or 1111 DEST elements are already in place; this is more or
1114 less the same loop that is in re_node_set_merge. */ 1112 less the same loop that is in re_node_set_merge. */
1115 dest->nelem += delta; 1113 dest->nelem += delta;
1116 if (delta > 0 && REG_VALID_INDEX (id)) 1114 if (delta > 0 && id >= 0)
1117 for (;;) 1115 for (;;)
1118 { 1116 {
1119 if (dest->elems[is] > dest->elems[id]) 1117 if (dest->elems[is] > dest->elems[id])
@@ -1127,7 +1125,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
1127 { 1125 {
1128 /* Slide from the bottom. */ 1126 /* Slide from the bottom. */
1129 dest->elems[id + delta] = dest->elems[id]; 1127 dest->elems[id + delta] = dest->elems[id];
1130 if (! REG_VALID_INDEX (--id)) 1128 if (--id < 0)
1131 break; 1129 break;
1132 } 1130 }
1133 } 1131 }
@@ -1142,7 +1140,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
1142 DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ 1140 DEST. Return value indicate the error code or REG_NOERROR if succeeded. */
1143 1141
1144static reg_errcode_t 1142static reg_errcode_t
1145internal_function __attribute_warn_unused_result__ 1143__attribute_warn_unused_result__
1146re_node_set_init_union (re_node_set *dest, const re_node_set *src1, 1144re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
1147 const re_node_set *src2) 1145 const re_node_set *src2)
1148{ 1146{
@@ -1151,7 +1149,7 @@ re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
1151 { 1149 {
1152 dest->alloc = src1->nelem + src2->nelem; 1150 dest->alloc = src1->nelem + src2->nelem;
1153 dest->elems = re_malloc (Idx, dest->alloc); 1151 dest->elems = re_malloc (Idx, dest->alloc);
1154 if (BE (dest->elems == NULL, 0)) 1152 if (__glibc_unlikely (dest->elems == NULL))
1155 return REG_ESPACE; 1153 return REG_ESPACE;
1156 } 1154 }
1157 else 1155 else
@@ -1195,7 +1193,7 @@ re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
1195 DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ 1193 DEST. Return value indicate the error code or REG_NOERROR if succeeded. */
1196 1194
1197static reg_errcode_t 1195static reg_errcode_t
1198internal_function __attribute_warn_unused_result__ 1196__attribute_warn_unused_result__
1199re_node_set_merge (re_node_set *dest, const re_node_set *src) 1197re_node_set_merge (re_node_set *dest, const re_node_set *src)
1200{ 1198{
1201 Idx is, id, sbase, delta; 1199 Idx is, id, sbase, delta;
@@ -1205,14 +1203,18 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
1205 { 1203 {
1206 Idx new_alloc = 2 * (src->nelem + dest->alloc); 1204 Idx new_alloc = 2 * (src->nelem + dest->alloc);
1207 Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc); 1205 Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc);
1208 if (BE (new_buffer == NULL, 0)) 1206 if (__glibc_unlikely (new_buffer == NULL))
1209 return REG_ESPACE; 1207 return REG_ESPACE;
1210 dest->elems = new_buffer; 1208 dest->elems = new_buffer;
1211 dest->alloc = new_alloc; 1209 dest->alloc = new_alloc;
1212 } 1210 }
1213 1211
1214 if (BE (dest->nelem == 0, 0)) 1212 if (__glibc_unlikely (dest->nelem == 0))
1215 { 1213 {
1214 /* Although we already guaranteed above that dest->alloc != 0 and
1215 therefore dest->elems != NULL, add a debug assertion to pacify
1216 GCC 11.2.1's -fanalyzer. */
1217 DEBUG_ASSERT (dest->elems);
1216 dest->nelem = src->nelem; 1218 dest->nelem = src->nelem;
1217 memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx)); 1219 memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
1218 return REG_NOERROR; 1220 return REG_NOERROR;
@@ -1221,8 +1223,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
1221 /* Copy into the top of DEST the items of SRC that are not 1223 /* Copy into the top of DEST the items of SRC that are not
1222 found in DEST. Maybe we could binary search in DEST? */ 1224 found in DEST. Maybe we could binary search in DEST? */
1223 for (sbase = dest->nelem + 2 * src->nelem, 1225 for (sbase = dest->nelem + 2 * src->nelem,
1224 is = src->nelem - 1, id = dest->nelem - 1; 1226 is = src->nelem - 1, id = dest->nelem - 1; is >= 0 && id >= 0; )
1225 REG_VALID_INDEX (is) && REG_VALID_INDEX (id); )
1226 { 1227 {
1227 if (dest->elems[id] == src->elems[is]) 1228 if (dest->elems[id] == src->elems[is])
1228 is--, id--; 1229 is--, id--;
@@ -1232,7 +1233,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
1232 --id; 1233 --id;
1233 } 1234 }
1234 1235
1235 if (REG_VALID_INDEX (is)) 1236 if (is >= 0)
1236 { 1237 {
1237 /* If DEST is exhausted, the remaining items of SRC must be unique. */ 1238 /* If DEST is exhausted, the remaining items of SRC must be unique. */
1238 sbase -= is + 1; 1239 sbase -= is + 1;
@@ -1261,7 +1262,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
1261 { 1262 {
1262 /* Slide from the bottom. */ 1263 /* Slide from the bottom. */
1263 dest->elems[id + delta] = dest->elems[id]; 1264 dest->elems[id + delta] = dest->elems[id];
1264 if (! REG_VALID_INDEX (--id)) 1265 if (--id < 0)
1265 { 1266 {
1266 /* Copy remaining SRC elements. */ 1267 /* Copy remaining SRC elements. */
1267 memcpy (dest->elems, dest->elems + sbase, 1268 memcpy (dest->elems, dest->elems + sbase,
@@ -1279,17 +1280,20 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
1279 Return true if successful. */ 1280 Return true if successful. */
1280 1281
1281static bool 1282static bool
1282internal_function __attribute_warn_unused_result__ 1283__attribute_warn_unused_result__
1283re_node_set_insert (re_node_set *set, Idx elem) 1284re_node_set_insert (re_node_set *set, Idx elem)
1284{ 1285{
1285 Idx idx; 1286 Idx idx;
1286 /* In case the set is empty. */ 1287 /* In case the set is empty. */
1287 if (set->alloc == 0) 1288 if (set->alloc == 0)
1288 return BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1); 1289 return __glibc_likely (re_node_set_init_1 (set, elem) == REG_NOERROR);
1289 1290
1290 if (BE (set->nelem, 0) == 0) 1291 if (__glibc_unlikely (set->nelem) == 0)
1291 { 1292 {
1292 /* We already guaranteed above that set->alloc != 0. */ 1293 /* Although we already guaranteed above that set->alloc != 0 and
1294 therefore set->elems != NULL, add a debug assertion to pacify
1295 GCC 11.2 -fanalyzer. */
1296 DEBUG_ASSERT (set->elems);
1293 set->elems[0] = elem; 1297 set->elems[0] = elem;
1294 ++set->nelem; 1298 ++set->nelem;
1295 return true; 1299 return true;
@@ -1301,7 +1305,7 @@ re_node_set_insert (re_node_set *set, Idx elem)
1301 Idx *new_elems; 1305 Idx *new_elems;
1302 set->alloc = set->alloc * 2; 1306 set->alloc = set->alloc * 2;
1303 new_elems = re_realloc (set->elems, Idx, set->alloc); 1307 new_elems = re_realloc (set->elems, Idx, set->alloc);
1304 if (BE (new_elems == NULL, 0)) 1308 if (__glibc_unlikely (new_elems == NULL))
1305 return false; 1309 return false;
1306 set->elems = new_elems; 1310 set->elems = new_elems;
1307 } 1311 }
@@ -1310,7 +1314,6 @@ re_node_set_insert (re_node_set *set, Idx elem)
1310 first element separately to skip a check in the inner loop. */ 1314 first element separately to skip a check in the inner loop. */
1311 if (elem < set->elems[0]) 1315 if (elem < set->elems[0])
1312 { 1316 {
1313 idx = 0;
1314 for (idx = set->nelem; idx > 0; idx--) 1317 for (idx = set->nelem; idx > 0; idx--)
1315 set->elems[idx] = set->elems[idx - 1]; 1318 set->elems[idx] = set->elems[idx - 1];
1316 } 1319 }
@@ -1318,6 +1321,7 @@ re_node_set_insert (re_node_set *set, Idx elem)
1318 { 1321 {
1319 for (idx = set->nelem; set->elems[idx - 1] > elem; idx--) 1322 for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
1320 set->elems[idx] = set->elems[idx - 1]; 1323 set->elems[idx] = set->elems[idx - 1];
1324 DEBUG_ASSERT (set->elems[idx - 1] < elem);
1321 } 1325 }
1322 1326
1323 /* Insert the new element. */ 1327 /* Insert the new element. */
@@ -1331,7 +1335,7 @@ re_node_set_insert (re_node_set *set, Idx elem)
1331 Return true if successful. */ 1335 Return true if successful. */
1332 1336
1333static bool 1337static bool
1334internal_function __attribute_warn_unused_result__ 1338__attribute_warn_unused_result__
1335re_node_set_insert_last (re_node_set *set, Idx elem) 1339re_node_set_insert_last (re_node_set *set, Idx elem)
1336{ 1340{
1337 /* Realloc if we need. */ 1341 /* Realloc if we need. */
@@ -1340,7 +1344,7 @@ re_node_set_insert_last (re_node_set *set, Idx elem)
1340 Idx *new_elems; 1344 Idx *new_elems;
1341 set->alloc = (set->alloc + 1) * 2; 1345 set->alloc = (set->alloc + 1) * 2;
1342 new_elems = re_realloc (set->elems, Idx, set->alloc); 1346 new_elems = re_realloc (set->elems, Idx, set->alloc);
1343 if (BE (new_elems == NULL, 0)) 1347 if (__glibc_unlikely (new_elems == NULL))
1344 return false; 1348 return false;
1345 set->elems = new_elems; 1349 set->elems = new_elems;
1346 } 1350 }
@@ -1354,13 +1358,13 @@ re_node_set_insert_last (re_node_set *set, Idx elem)
1354 Return true if SET1 and SET2 are equivalent. */ 1358 Return true if SET1 and SET2 are equivalent. */
1355 1359
1356static bool 1360static bool
1357internal_function __attribute__ ((pure)) 1361__attribute__ ((pure))
1358re_node_set_compare (const re_node_set *set1, const re_node_set *set2) 1362re_node_set_compare (const re_node_set *set1, const re_node_set *set2)
1359{ 1363{
1360 Idx i; 1364 Idx i;
1361 if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem) 1365 if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)
1362 return false; 1366 return false;
1363 for (i = set1->nelem ; REG_VALID_INDEX (--i) ; ) 1367 for (i = set1->nelem ; --i >= 0 ; )
1364 if (set1->elems[i] != set2->elems[i]) 1368 if (set1->elems[i] != set2->elems[i])
1365 return false; 1369 return false;
1366 return true; 1370 return true;
@@ -1369,11 +1373,11 @@ re_node_set_compare (const re_node_set *set1, const re_node_set *set2)
1369/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */ 1373/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */
1370 1374
1371static Idx 1375static Idx
1372internal_function __attribute__ ((pure)) 1376__attribute__ ((pure))
1373re_node_set_contains (const re_node_set *set, Idx elem) 1377re_node_set_contains (const re_node_set *set, Idx elem)
1374{ 1378{
1375 __re_size_t idx, right, mid; 1379 __re_size_t idx, right, mid;
1376 if (! REG_VALID_NONZERO_INDEX (set->nelem)) 1380 if (set->nelem <= 0)
1377 return 0; 1381 return 0;
1378 1382
1379 /* Binary search the element. */ 1383 /* Binary search the element. */
@@ -1391,7 +1395,6 @@ re_node_set_contains (const re_node_set *set, Idx elem)
1391} 1395}
1392 1396
1393static void 1397static void
1394internal_function
1395re_node_set_remove_at (re_node_set *set, Idx idx) 1398re_node_set_remove_at (re_node_set *set, Idx idx)
1396{ 1399{
1397 if (idx < 0 || idx >= set->nelem) 1400 if (idx < 0 || idx >= set->nelem)
@@ -1403,13 +1406,12 @@ re_node_set_remove_at (re_node_set *set, Idx idx)
1403 1406
1404 1407
1405/* Add the token TOKEN to dfa->nodes, and return the index of the token. 1408/* Add the token TOKEN to dfa->nodes, and return the index of the token.
1406 Or return REG_MISSING if an error occurred. */ 1409 Or return -1 if an error occurred. */
1407 1410
1408static Idx 1411static Idx
1409internal_function
1410re_dfa_add_node (re_dfa_t *dfa, re_token_t token) 1412re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
1411{ 1413{
1412 if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0)) 1414 if (__glibc_unlikely (dfa->nodes_len >= dfa->nodes_alloc))
1413 { 1415 {
1414 size_t new_nodes_alloc = dfa->nodes_alloc * 2; 1416 size_t new_nodes_alloc = dfa->nodes_alloc * 2;
1415 Idx *new_nexts, *new_indices; 1417 Idx *new_nexts, *new_indices;
@@ -1420,20 +1422,27 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
1420 const size_t max_object_size = MAX (sizeof (re_token_t), 1422 const size_t max_object_size = MAX (sizeof (re_token_t),
1421 MAX (sizeof (re_node_set), 1423 MAX (sizeof (re_node_set),
1422 sizeof (Idx))); 1424 sizeof (Idx)));
1423 if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < new_nodes_alloc, 0)) 1425 if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size)
1424 return REG_MISSING; 1426 < new_nodes_alloc))
1427 return -1;
1425 1428
1426 new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc); 1429 new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
1427 if (BE (new_nodes == NULL, 0)) 1430 if (__glibc_unlikely (new_nodes == NULL))
1428 return REG_MISSING; 1431 return -1;
1429 dfa->nodes = new_nodes; 1432 dfa->nodes = new_nodes;
1430 new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc); 1433 new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc);
1431 new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc); 1434 new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc);
1432 new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc); 1435 new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);
1433 new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc); 1436 new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);
1434 if (BE (new_nexts == NULL || new_indices == NULL 1437 if (__glibc_unlikely (new_nexts == NULL || new_indices == NULL
1435 || new_edests == NULL || new_eclosures == NULL, 0)) 1438 || new_edests == NULL || new_eclosures == NULL))
1436 return REG_MISSING; 1439 {
1440 re_free (new_nexts);
1441 re_free (new_indices);
1442 re_free (new_edests);
1443 re_free (new_eclosures);
1444 return -1;
1445 }
1437 dfa->nexts = new_nexts; 1446 dfa->nexts = new_nexts;
1438 dfa->org_indices = new_indices; 1447 dfa->org_indices = new_indices;
1439 dfa->edests = new_edests; 1448 dfa->edests = new_edests;
@@ -1447,14 +1456,13 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
1447 ((token.type == OP_PERIOD && dfa->mb_cur_max > 1) 1456 ((token.type == OP_PERIOD && dfa->mb_cur_max > 1)
1448 || token.type == COMPLEX_BRACKET); 1457 || token.type == COMPLEX_BRACKET);
1449#endif 1458#endif
1450 dfa->nexts[dfa->nodes_len] = REG_MISSING; 1459 dfa->nexts[dfa->nodes_len] = -1;
1451 re_node_set_init_empty (dfa->edests + dfa->nodes_len); 1460 re_node_set_init_empty (dfa->edests + dfa->nodes_len);
1452 re_node_set_init_empty (dfa->eclosures + dfa->nodes_len); 1461 re_node_set_init_empty (dfa->eclosures + dfa->nodes_len);
1453 return dfa->nodes_len++; 1462 return dfa->nodes_len++;
1454} 1463}
1455 1464
1456static re_hashval_t 1465static re_hashval_t
1457internal_function
1458calc_state_hash (const re_node_set *nodes, unsigned int context) 1466calc_state_hash (const re_node_set *nodes, unsigned int context)
1459{ 1467{
1460 re_hashval_t hash = nodes->nelem + context; 1468 re_hashval_t hash = nodes->nelem + context;
@@ -1474,7 +1482,7 @@ calc_state_hash (const re_node_set *nodes, unsigned int context)
1474 optimization. */ 1482 optimization. */
1475 1483
1476static re_dfastate_t * 1484static re_dfastate_t *
1477internal_function __attribute_warn_unused_result__ 1485__attribute_warn_unused_result__
1478re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, 1486re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
1479 const re_node_set *nodes) 1487 const re_node_set *nodes)
1480{ 1488{
@@ -1482,11 +1490,11 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
1482 re_dfastate_t *new_state; 1490 re_dfastate_t *new_state;
1483 struct re_state_table_entry *spot; 1491 struct re_state_table_entry *spot;
1484 Idx i; 1492 Idx i;
1485#ifdef lint 1493#if defined GCC_LINT || defined lint
1486 /* Suppress bogus uninitialized-variable warnings. */ 1494 /* Suppress bogus uninitialized-variable warnings. */
1487 *err = REG_NOERROR; 1495 *err = REG_NOERROR;
1488#endif 1496#endif
1489 if (BE (nodes->nelem == 0, 0)) 1497 if (__glibc_unlikely (nodes->nelem == 0))
1490 { 1498 {
1491 *err = REG_NOERROR; 1499 *err = REG_NOERROR;
1492 return NULL; 1500 return NULL;
@@ -1505,7 +1513,7 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
1505 1513
1506 /* There are no appropriate state in the dfa, create the new one. */ 1514 /* There are no appropriate state in the dfa, create the new one. */
1507 new_state = create_ci_newstate (dfa, nodes, hash); 1515 new_state = create_ci_newstate (dfa, nodes, hash);
1508 if (BE (new_state == NULL, 0)) 1516 if (__glibc_unlikely (new_state == NULL))
1509 *err = REG_ESPACE; 1517 *err = REG_ESPACE;
1510 1518
1511 return new_state; 1519 return new_state;
@@ -1522,7 +1530,7 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
1522 optimization. */ 1530 optimization. */
1523 1531
1524static re_dfastate_t * 1532static re_dfastate_t *
1525internal_function __attribute_warn_unused_result__ 1533__attribute_warn_unused_result__
1526re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa, 1534re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
1527 const re_node_set *nodes, unsigned int context) 1535 const re_node_set *nodes, unsigned int context)
1528{ 1536{
@@ -1530,7 +1538,7 @@ re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
1530 re_dfastate_t *new_state; 1538 re_dfastate_t *new_state;
1531 struct re_state_table_entry *spot; 1539 struct re_state_table_entry *spot;
1532 Idx i; 1540 Idx i;
1533#ifdef lint 1541#if defined GCC_LINT || defined lint
1534 /* Suppress bogus uninitialized-variable warnings. */ 1542 /* Suppress bogus uninitialized-variable warnings. */
1535 *err = REG_NOERROR; 1543 *err = REG_NOERROR;
1536#endif 1544#endif
@@ -1552,7 +1560,7 @@ re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
1552 } 1560 }
1553 /* There are no appropriate state in 'dfa', create the new one. */ 1561 /* There are no appropriate state in 'dfa', create the new one. */
1554 new_state = create_cd_newstate (dfa, nodes, context, hash); 1562 new_state = create_cd_newstate (dfa, nodes, context, hash);
1555 if (BE (new_state == NULL, 0)) 1563 if (__glibc_unlikely (new_state == NULL))
1556 *err = REG_ESPACE; 1564 *err = REG_ESPACE;
1557 1565
1558 return new_state; 1566 return new_state;
@@ -1573,7 +1581,7 @@ register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
1573 1581
1574 newstate->hash = hash; 1582 newstate->hash = hash;
1575 err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem); 1583 err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);
1576 if (BE (err != REG_NOERROR, 0)) 1584 if (__glibc_unlikely (err != REG_NOERROR))
1577 return REG_ESPACE; 1585 return REG_ESPACE;
1578 for (i = 0; i < newstate->nodes.nelem; i++) 1586 for (i = 0; i < newstate->nodes.nelem; i++)
1579 { 1587 {
@@ -1584,12 +1592,12 @@ register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
1584 } 1592 }
1585 1593
1586 spot = dfa->state_table + (hash & dfa->state_hash_mask); 1594 spot = dfa->state_table + (hash & dfa->state_hash_mask);
1587 if (BE (spot->alloc <= spot->num, 0)) 1595 if (__glibc_unlikely (spot->alloc <= spot->num))
1588 { 1596 {
1589 Idx new_alloc = 2 * spot->num + 2; 1597 Idx new_alloc = 2 * spot->num + 2;
1590 re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *, 1598 re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,
1591 new_alloc); 1599 new_alloc);
1592 if (BE (new_array == NULL, 0)) 1600 if (__glibc_unlikely (new_array == NULL))
1593 return REG_ESPACE; 1601 return REG_ESPACE;
1594 spot->array = new_array; 1602 spot->array = new_array;
1595 spot->alloc = new_alloc; 1603 spot->alloc = new_alloc;
@@ -1618,7 +1626,7 @@ free_state (re_dfastate_t *state)
1618 Return the new state if succeeded, otherwise return NULL. */ 1626 Return the new state if succeeded, otherwise return NULL. */
1619 1627
1620static re_dfastate_t * 1628static re_dfastate_t *
1621internal_function __attribute_warn_unused_result__ 1629__attribute_warn_unused_result__
1622create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, 1630create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1623 re_hashval_t hash) 1631 re_hashval_t hash)
1624{ 1632{
@@ -1627,10 +1635,10 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1627 re_dfastate_t *newstate; 1635 re_dfastate_t *newstate;
1628 1636
1629 newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); 1637 newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
1630 if (BE (newstate == NULL, 0)) 1638 if (__glibc_unlikely (newstate == NULL))
1631 return NULL; 1639 return NULL;
1632 err = re_node_set_init_copy (&newstate->nodes, nodes); 1640 err = re_node_set_init_copy (&newstate->nodes, nodes);
1633 if (BE (err != REG_NOERROR, 0)) 1641 if (__glibc_unlikely (err != REG_NOERROR))
1634 { 1642 {
1635 re_free (newstate); 1643 re_free (newstate);
1636 return NULL; 1644 return NULL;
@@ -1656,7 +1664,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1656 newstate->has_constraint = 1; 1664 newstate->has_constraint = 1;
1657 } 1665 }
1658 err = register_state (dfa, newstate, hash); 1666 err = register_state (dfa, newstate, hash);
1659 if (BE (err != REG_NOERROR, 0)) 1667 if (__glibc_unlikely (err != REG_NOERROR))
1660 { 1668 {
1661 free_state (newstate); 1669 free_state (newstate);
1662 newstate = NULL; 1670 newstate = NULL;
@@ -1668,7 +1676,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1668 Return the new state if succeeded, otherwise return NULL. */ 1676 Return the new state if succeeded, otherwise return NULL. */
1669 1677
1670static re_dfastate_t * 1678static re_dfastate_t *
1671internal_function __attribute_warn_unused_result__ 1679__attribute_warn_unused_result__
1672create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, 1680create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1673 unsigned int context, re_hashval_t hash) 1681 unsigned int context, re_hashval_t hash)
1674{ 1682{
@@ -1677,10 +1685,10 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1677 re_dfastate_t *newstate; 1685 re_dfastate_t *newstate;
1678 1686
1679 newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); 1687 newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
1680 if (BE (newstate == NULL, 0)) 1688 if (__glibc_unlikely (newstate == NULL))
1681 return NULL; 1689 return NULL;
1682 err = re_node_set_init_copy (&newstate->nodes, nodes); 1690 err = re_node_set_init_copy (&newstate->nodes, nodes);
1683 if (BE (err != REG_NOERROR, 0)) 1691 if (__glibc_unlikely (err != REG_NOERROR))
1684 { 1692 {
1685 re_free (newstate); 1693 re_free (newstate);
1686 return NULL; 1694 return NULL;
@@ -1711,15 +1719,19 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1711 { 1719 {
1712 if (newstate->entrance_nodes == &newstate->nodes) 1720 if (newstate->entrance_nodes == &newstate->nodes)
1713 { 1721 {
1714 newstate->entrance_nodes = re_malloc (re_node_set, 1); 1722 re_node_set *entrance_nodes = re_malloc (re_node_set, 1);
1715 if (BE (newstate->entrance_nodes == NULL, 0)) 1723 if (__glibc_unlikely (entrance_nodes == NULL))
1716 { 1724 {
1717 free_state (newstate); 1725 free_state (newstate);
1718 return NULL; 1726 return NULL;
1719 } 1727 }
1728 newstate->entrance_nodes = entrance_nodes;
1720 if (re_node_set_init_copy (newstate->entrance_nodes, nodes) 1729 if (re_node_set_init_copy (newstate->entrance_nodes, nodes)
1721 != REG_NOERROR) 1730 != REG_NOERROR)
1722 return NULL; 1731 {
1732 free_state (newstate);
1733 return NULL;
1734 }
1723 nctx_nodes = 0; 1735 nctx_nodes = 0;
1724 newstate->has_constraint = 1; 1736 newstate->has_constraint = 1;
1725 } 1737 }
@@ -1732,7 +1744,7 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1732 } 1744 }
1733 } 1745 }
1734 err = register_state (dfa, newstate, hash); 1746 err = register_state (dfa, newstate, hash);
1735 if (BE (err != REG_NOERROR, 0)) 1747 if (__glibc_unlikely (err != REG_NOERROR))
1736 { 1748 {
1737 free_state (newstate); 1749 free_state (newstate);
1738 newstate = NULL; 1750 newstate = NULL;