diff options
| author | Noam Postavsky | 2016-10-24 19:54:29 -0400 |
|---|---|---|
| committer | Noam Postavsky | 2016-10-25 20:15:33 -0400 |
| commit | fee4cef7d720e98922858e19b3161358041ec141 (patch) | |
| tree | 191cdafd145e0ff5e403b95080f7baaeefbd170c | |
| parent | 4c3f7387df339176a94f49895c92fa6a5f526bae (diff) | |
| download | emacs-fee4cef7d720e98922858e19b3161358041ec141.tar.gz emacs-fee4cef7d720e98922858e19b3161358041ec141.zip | |
Revert fixes to allocation of regex matching
The fix was not complete, and completing it was proving too complicated.
- Revert "* src/regex.c (re_search_2): Make new code safe for
-Wjump-misses-init."
This reverts commit c2a17924a57483d14692c8913edbe8ad24b5ffbb.
- Revert "Port to GCC 6.2.1 + --enable-gcc-warnings"
This reverts commit f6134bbda259c115c06d4a9a3ab5c39340a15949.
- Revert "Fix handling of allocation in regex matching"
This reverts commit ad66b3fadb7ae22a4cbb82bb1507c39ceadf3897.
- Revert "Fix handling of buffer relocation in regex.c functions"
This reverts commit ee04aedc723b035eedaf975422d4eb242894121b.
| -rw-r--r-- | src/dired.c | 4 | ||||
| -rw-r--r-- | src/regex.c | 73 | ||||
| -rw-r--r-- | src/regex.h | 4 | ||||
| -rw-r--r-- | src/search.c | 40 |
4 files changed, 14 insertions, 107 deletions
diff --git a/src/dired.c b/src/dired.c index 006f74c834d..dba575ce4c2 100644 --- a/src/dired.c +++ b/src/dired.c | |||
| @@ -259,11 +259,9 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, | |||
| 259 | QUIT; | 259 | QUIT; |
| 260 | 260 | ||
| 261 | bool wanted = (NILP (match) | 261 | bool wanted = (NILP (match) |
| 262 | || (re_match_object = name, | 262 | || re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0); |
| 263 | re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0)); | ||
| 264 | 263 | ||
| 265 | immediate_quit = 0; | 264 | immediate_quit = 0; |
| 266 | re_match_object = Qnil; /* Stop protecting name from GC. */ | ||
| 267 | 265 | ||
| 268 | if (wanted) | 266 | if (wanted) |
| 269 | { | 267 | { |
diff --git a/src/regex.c b/src/regex.c index b12e95b38c0..56b18e6b5bb 100644 --- a/src/regex.c +++ b/src/regex.c | |||
| @@ -1438,62 +1438,11 @@ typedef struct | |||
| 1438 | #define NEXT_FAILURE_HANDLE(h) fail_stack.stack[(h) - 3].integer | 1438 | #define NEXT_FAILURE_HANDLE(h) fail_stack.stack[(h) - 3].integer |
| 1439 | #define TOP_FAILURE_HANDLE() fail_stack.frame | 1439 | #define TOP_FAILURE_HANDLE() fail_stack.frame |
| 1440 | 1440 | ||
| 1441 | #ifdef emacs | ||
| 1442 | # define STR_BASE_PTR(obj) \ | ||
| 1443 | (NILP (obj) ? current_buffer->text->beg \ | ||
| 1444 | : STRINGP (obj) ? SDATA (obj) \ | ||
| 1445 | : NULL) | ||
| 1446 | #else | ||
| 1447 | # define STR_BASE_PTR(obj) NULL | ||
| 1448 | #endif | ||
| 1449 | 1441 | ||
| 1450 | #define ENSURE_FAIL_STACK(space) \ | 1442 | #define ENSURE_FAIL_STACK(space) \ |
| 1451 | while (REMAINING_AVAIL_SLOTS <= space) { \ | 1443 | while (REMAINING_AVAIL_SLOTS <= space) { \ |
| 1452 | re_char *orig_base = STR_BASE_PTR (re_match_object); \ | ||
| 1453 | bool might_relocate = orig_base != NULL; \ | ||
| 1454 | ptrdiff_t string1_off, end1_off, end_match_1_off; \ | ||
| 1455 | ptrdiff_t string2_off, end2_off, end_match_2_off; \ | ||
| 1456 | ptrdiff_t d_off, dend_off, dfail_off; \ | ||
| 1457 | if (might_relocate) \ | ||
| 1458 | { \ | ||
| 1459 | if (string1) \ | ||
| 1460 | { \ | ||
| 1461 | string1_off = string1 - orig_base; \ | ||
| 1462 | end1_off = end1 - orig_base; \ | ||
| 1463 | end_match_1_off = end_match_1 - orig_base; \ | ||
| 1464 | } \ | ||
| 1465 | if (string2) \ | ||
| 1466 | { \ | ||
| 1467 | string2_off = string2 - orig_base; \ | ||
| 1468 | end2_off = end2 - orig_base; \ | ||
| 1469 | end_match_2_off = end_match_2 - orig_base; \ | ||
| 1470 | } \ | ||
| 1471 | d_off = d - orig_base; \ | ||
| 1472 | dend_off = dend - orig_base; \ | ||
| 1473 | dfail_off = dfail - orig_base; \ | ||
| 1474 | } \ | ||
| 1475 | if (!GROW_FAIL_STACK (fail_stack)) \ | 1444 | if (!GROW_FAIL_STACK (fail_stack)) \ |
| 1476 | return -2; \ | 1445 | return -2; \ |
| 1477 | /* In Emacs, GROW_FAIL_STACK might relocate string pointers. */ \ | ||
| 1478 | if (might_relocate) \ | ||
| 1479 | { \ | ||
| 1480 | re_char *new_base = STR_BASE_PTR (re_match_object); \ | ||
| 1481 | if (string1) \ | ||
| 1482 | { \ | ||
| 1483 | string1 = new_base + string1_off; \ | ||
| 1484 | end1 = new_base + end1_off; \ | ||
| 1485 | end_match_1 = new_base + end_match_1_off; \ | ||
| 1486 | } \ | ||
| 1487 | if (string2) \ | ||
| 1488 | { \ | ||
| 1489 | string2 = new_base + string2_off; \ | ||
| 1490 | end2 = new_base + end2_off; \ | ||
| 1491 | end_match_2 = new_base + end_match_2_off; \ | ||
| 1492 | } \ | ||
| 1493 | d = new_base + d_off; \ | ||
| 1494 | dend = new_base + dend_off; \ | ||
| 1495 | dfail = new_base + dfail_off; \ | ||
| 1496 | } \ | ||
| 1497 | DEBUG_PRINT ("\n Doubled stack; size now: %zd\n", (fail_stack).size);\ | 1446 | DEBUG_PRINT ("\n Doubled stack; size now: %zd\n", (fail_stack).size);\ |
| 1498 | DEBUG_PRINT (" slots available: %zd\n", REMAINING_AVAIL_SLOTS);\ | 1447 | DEBUG_PRINT (" slots available: %zd\n", REMAINING_AVAIL_SLOTS);\ |
| 1499 | } | 1448 | } |
| @@ -4380,10 +4329,6 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, size_t size1, | |||
| 4380 | /* Loop through the string, looking for a place to start matching. */ | 4329 | /* Loop through the string, looking for a place to start matching. */ |
| 4381 | for (;;) | 4330 | for (;;) |
| 4382 | { | 4331 | { |
| 4383 | ptrdiff_t offset1, offset2; | ||
| 4384 | re_char *orig_base; | ||
| 4385 | bool might_relocate; | ||
| 4386 | |||
| 4387 | /* If the pattern is anchored, | 4332 | /* If the pattern is anchored, |
| 4388 | skip quickly past places we cannot match. | 4333 | skip quickly past places we cannot match. |
| 4389 | We don't bother to treat startpos == 0 specially | 4334 | We don't bother to treat startpos == 0 specially |
| @@ -4500,17 +4445,6 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, size_t size1, | |||
| 4500 | && !bufp->can_be_null) | 4445 | && !bufp->can_be_null) |
| 4501 | return -1; | 4446 | return -1; |
| 4502 | 4447 | ||
| 4503 | /* re_match_2_internal may allocate, relocating the Lisp text | ||
| 4504 | object that we're searching. */ | ||
| 4505 | IF_LINT (offset2 = 0); /* Work around GCC bug 78081. */ | ||
| 4506 | orig_base = STR_BASE_PTR (re_match_object); | ||
| 4507 | might_relocate = orig_base != NULL; | ||
| 4508 | if (might_relocate) | ||
| 4509 | { | ||
| 4510 | if (string1) offset1 = string1 - orig_base; | ||
| 4511 | if (string2) offset2 = string2 - orig_base; | ||
| 4512 | } | ||
| 4513 | |||
| 4514 | val = re_match_2_internal (bufp, string1, size1, string2, size2, | 4448 | val = re_match_2_internal (bufp, string1, size1, string2, size2, |
| 4515 | startpos, regs, stop); | 4449 | startpos, regs, stop); |
| 4516 | 4450 | ||
| @@ -4520,13 +4454,6 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, size_t size1, | |||
| 4520 | if (val == -2) | 4454 | if (val == -2) |
| 4521 | return -2; | 4455 | return -2; |
| 4522 | 4456 | ||
| 4523 | if (might_relocate) | ||
| 4524 | { | ||
| 4525 | re_char *new_base = STR_BASE_PTR (re_match_object); | ||
| 4526 | if (string1) string1 = offset1 + new_base; | ||
| 4527 | if (string2) string2 = offset2 + new_base; | ||
| 4528 | } | ||
| 4529 | |||
| 4530 | advance: | 4457 | advance: |
| 4531 | if (!range) | 4458 | if (!range) |
| 4532 | break; | 4459 | break; |
diff --git a/src/regex.h b/src/regex.h index 61c771c045f..51f4424ce94 100644 --- a/src/regex.h +++ b/src/regex.h | |||
| @@ -169,9 +169,7 @@ extern reg_syntax_t re_syntax_options; | |||
| 169 | #ifdef emacs | 169 | #ifdef emacs |
| 170 | # include "lisp.h" | 170 | # include "lisp.h" |
| 171 | /* In Emacs, this is the string or buffer in which we are matching. | 171 | /* In Emacs, this is the string or buffer in which we are matching. |
| 172 | It is used for looking up syntax properties, and also to recompute | 172 | It is used for looking up syntax properties. |
| 173 | pointers in case the object is relocated as a side effect of | ||
| 174 | calling malloc (if it calls r_alloc_sbrk in ralloc.c). | ||
| 175 | 173 | ||
| 176 | If the value is a Lisp string object, we are matching text in that | 174 | If the value is a Lisp string object, we are matching text in that |
| 177 | string; if it's nil, we are matching text in the current buffer; if | 175 | string; if it's nil, we are matching text in the current buffer; if |
diff --git a/src/search.c b/src/search.c index b50e7f032d5..fa5ac44de9d 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -287,10 +287,8 @@ looking_at_1 (Lisp_Object string, bool posix) | |||
| 287 | immediate_quit = 1; | 287 | immediate_quit = 1; |
| 288 | QUIT; /* Do a pending quit right away, to avoid paradoxical behavior */ | 288 | QUIT; /* Do a pending quit right away, to avoid paradoxical behavior */ |
| 289 | 289 | ||
| 290 | /* Get pointers and sizes of the two strings that make up the | 290 | /* Get pointers and sizes of the two strings |
| 291 | visible portion of the buffer. Note that we can use pointers | 291 | that make up the visible portion of the buffer. */ |
| 292 | here, unlike in search_buffer, because we only call re_match_2 | ||
| 293 | once, after which we never use the pointers again. */ | ||
| 294 | 292 | ||
| 295 | p1 = BEGV_ADDR; | 293 | p1 = BEGV_ADDR; |
| 296 | s1 = GPT_BYTE - BEGV_BYTE; | 294 | s1 = GPT_BYTE - BEGV_BYTE; |
| @@ -409,7 +407,6 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start, | |||
| 409 | (NILP (Vinhibit_changing_match_data) | 407 | (NILP (Vinhibit_changing_match_data) |
| 410 | ? &search_regs : NULL)); | 408 | ? &search_regs : NULL)); |
| 411 | immediate_quit = 0; | 409 | immediate_quit = 0; |
| 412 | re_match_object = Qnil; /* Stop protecting string from GC. */ | ||
| 413 | 410 | ||
| 414 | /* Set last_thing_searched only when match data is changed. */ | 411 | /* Set last_thing_searched only when match data is changed. */ |
| 415 | if (NILP (Vinhibit_changing_match_data)) | 412 | if (NILP (Vinhibit_changing_match_data)) |
| @@ -480,7 +477,6 @@ fast_string_match_internal (Lisp_Object regexp, Lisp_Object string, | |||
| 480 | SBYTES (string), 0, | 477 | SBYTES (string), 0, |
| 481 | SBYTES (string), 0); | 478 | SBYTES (string), 0); |
| 482 | immediate_quit = 0; | 479 | immediate_quit = 0; |
| 483 | re_match_object = Qnil; /* Stop protecting string from GC. */ | ||
| 484 | return val; | 480 | return val; |
| 485 | } | 481 | } |
| 486 | 482 | ||
| @@ -568,7 +564,6 @@ fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 568 | len = re_match_2 (buf, (char *) p1, s1, (char *) p2, s2, | 564 | len = re_match_2 (buf, (char *) p1, s1, (char *) p2, s2, |
| 569 | pos_byte, NULL, limit_byte); | 565 | pos_byte, NULL, limit_byte); |
| 570 | immediate_quit = 0; | 566 | immediate_quit = 0; |
| 571 | re_match_object = Qnil; /* Stop protecting string from GC. */ | ||
| 572 | 567 | ||
| 573 | return len; | 568 | return len; |
| 574 | } | 569 | } |
| @@ -1183,8 +1178,8 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 1183 | 1178 | ||
| 1184 | if (RE && !(trivial_regexp_p (string) && NILP (Vsearch_spaces_regexp))) | 1179 | if (RE && !(trivial_regexp_p (string) && NILP (Vsearch_spaces_regexp))) |
| 1185 | { | 1180 | { |
| 1186 | unsigned char *base; | 1181 | unsigned char *p1, *p2; |
| 1187 | ptrdiff_t off1, off2, s1, s2; | 1182 | ptrdiff_t s1, s2; |
| 1188 | struct re_pattern_buffer *bufp; | 1183 | struct re_pattern_buffer *bufp; |
| 1189 | 1184 | ||
| 1190 | bufp = compile_pattern (string, | 1185 | bufp = compile_pattern (string, |
| @@ -1198,19 +1193,16 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 1198 | can take too long. */ | 1193 | can take too long. */ |
| 1199 | QUIT; /* Do a pending quit right away, | 1194 | QUIT; /* Do a pending quit right away, |
| 1200 | to avoid paradoxical behavior */ | 1195 | to avoid paradoxical behavior */ |
| 1201 | /* Get offsets and sizes of the two strings that make up the | 1196 | /* Get pointers and sizes of the two strings |
| 1202 | visible portion of the buffer. We compute offsets instead of | 1197 | that make up the visible portion of the buffer. */ |
| 1203 | pointers because re_search_2 may call malloc and therefore | ||
| 1204 | change the buffer text address. */ | ||
| 1205 | 1198 | ||
| 1206 | base = current_buffer->text->beg; | 1199 | p1 = BEGV_ADDR; |
| 1207 | off1 = BEGV_ADDR - base; | ||
| 1208 | s1 = GPT_BYTE - BEGV_BYTE; | 1200 | s1 = GPT_BYTE - BEGV_BYTE; |
| 1209 | off2 = GAP_END_ADDR - base; | 1201 | p2 = GAP_END_ADDR; |
| 1210 | s2 = ZV_BYTE - GPT_BYTE; | 1202 | s2 = ZV_BYTE - GPT_BYTE; |
| 1211 | if (s1 < 0) | 1203 | if (s1 < 0) |
| 1212 | { | 1204 | { |
| 1213 | off2 = off1; | 1205 | p2 = p1; |
| 1214 | s2 = ZV_BYTE - BEGV_BYTE; | 1206 | s2 = ZV_BYTE - BEGV_BYTE; |
| 1215 | s1 = 0; | 1207 | s1 = 0; |
| 1216 | } | 1208 | } |
| @@ -1225,16 +1217,12 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 1225 | { | 1217 | { |
| 1226 | ptrdiff_t val; | 1218 | ptrdiff_t val; |
| 1227 | 1219 | ||
| 1228 | val = re_search_2 (bufp, | 1220 | val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, |
| 1229 | (char*) (base + off1), s1, | ||
| 1230 | (char*) (base + off2), s2, | ||
| 1231 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, | 1221 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, |
| 1232 | (NILP (Vinhibit_changing_match_data) | 1222 | (NILP (Vinhibit_changing_match_data) |
| 1233 | ? &search_regs : &search_regs_1), | 1223 | ? &search_regs : &search_regs_1), |
| 1234 | /* Don't allow match past current point */ | 1224 | /* Don't allow match past current point */ |
| 1235 | pos_byte - BEGV_BYTE); | 1225 | pos_byte - BEGV_BYTE); |
| 1236 | /* Update 'base' due to possible relocation inside re_search_2. */ | ||
| 1237 | base = current_buffer->text->beg; | ||
| 1238 | if (val == -2) | 1226 | if (val == -2) |
| 1239 | { | 1227 | { |
| 1240 | matcher_overflow (); | 1228 | matcher_overflow (); |
| @@ -1274,15 +1262,11 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 1274 | { | 1262 | { |
| 1275 | ptrdiff_t val; | 1263 | ptrdiff_t val; |
| 1276 | 1264 | ||
| 1277 | val = re_search_2 (bufp, | 1265 | val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, |
| 1278 | (char*) (base + off1), s1, | 1266 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, |
| 1279 | (char*) (base + off2), s2, | ||
| 1280 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, | ||
| 1281 | (NILP (Vinhibit_changing_match_data) | 1267 | (NILP (Vinhibit_changing_match_data) |
| 1282 | ? &search_regs : &search_regs_1), | 1268 | ? &search_regs : &search_regs_1), |
| 1283 | lim_byte - BEGV_BYTE); | 1269 | lim_byte - BEGV_BYTE); |
| 1284 | /* Update 'base' due to possible relocation inside re_search_2. */ | ||
| 1285 | base = current_buffer->text->beg; | ||
| 1286 | if (val == -2) | 1270 | if (val == -2) |
| 1287 | { | 1271 | { |
| 1288 | matcher_overflow (); | 1272 | matcher_overflow (); |