Skip to content

Commit 0d30259

Browse files
hs-apotellparrt
authored andcommitted
Fixing crash bug in TokenStreamRewriter
Order of operations issue - use before deleting not vice-versa. Signed-off-by: HS <[email protected]>
1 parent 990fbc2 commit 0d30259

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

runtime/Cpp/runtime/src/TokenStreamRewriter.cpp

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
1+
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
22
* Use of this file is governed by the BSD 3-clause license that
33
* can be found in the LICENSE.txt file in the project root.
44
*/
@@ -313,6 +313,10 @@ std::string TokenStreamRewriter::getText(const std::string &programName, const I
313313
std::unordered_map<size_t, TokenStreamRewriter::RewriteOperation*> TokenStreamRewriter::reduceToSingleOperationPerIndex(
314314
std::vector<TokenStreamRewriter::RewriteOperation*> &rewrites) {
315315

316+
// Reset the instructionIndex
317+
for (size_t i = 0; i < rewrites.size(); ++i) {
318+
rewrites[i]->instructionIndex = i;
319+
}
316320

317321
// WALK REPLACES
318322
for (size_t i = 0; i < rewrites.size(); ++i) {
@@ -327,35 +331,34 @@ std::unordered_map<size_t, TokenStreamRewriter::RewriteOperation*> TokenStreamRe
327331
if (iop->index == rop->index) {
328332
// E.g., insert before 2, delete 2..2; update replace
329333
// text to include insert before, kill insert
330-
delete rewrites[iop->instructionIndex];
331-
rewrites[iop->instructionIndex] = nullptr;
332334
rop->text = iop->text + (!rop->text.empty() ? rop->text : "");
335+
rewrites[iop->instructionIndex] = nullptr;
336+
delete iop;
333337
}
334338
else if (iop->index > rop->index && iop->index <= rop->lastIndex) {
335339
// delete insert as it's a no-op.
336-
delete rewrites[iop->instructionIndex];
337340
rewrites[iop->instructionIndex] = nullptr;
341+
delete iop;
338342
}
339343
}
340344
// Drop any prior replaces contained within
341345
std::vector<ReplaceOp*> prevReplaces = getKindOfOps<ReplaceOp>(rewrites, i);
342346
for (auto *prevRop : prevReplaces) {
343347
if (prevRop->index >= rop->index && prevRop->lastIndex <= rop->lastIndex) {
344348
// delete replace as it's a no-op.
345-
delete rewrites[prevRop->instructionIndex];
346349
rewrites[prevRop->instructionIndex] = nullptr;
350+
delete prevRop;
347351
continue;
348352
}
349353
// throw exception unless disjoint or identical
350354
bool disjoint = prevRop->lastIndex < rop->index || prevRop->index > rop->lastIndex;
351355
// Delete special case of replace (text==null):
352356
// D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right)
353357
if (prevRop->text.empty() && rop->text.empty() && !disjoint) {
354-
delete rewrites[prevRop->instructionIndex];
355-
rewrites[prevRop->instructionIndex] = nullptr; // kill first delete
356358
rop->index = std::min(prevRop->index, rop->index);
357359
rop->lastIndex = std::max(prevRop->lastIndex, rop->lastIndex);
358-
std::cout << "new rop " << rop << std::endl;
360+
rewrites[prevRop->instructionIndex] = nullptr; // kill first delete
361+
delete prevRop;
359362
}
360363
else if (!disjoint) {
361364
throw IllegalArgumentException("replace op boundaries of " + rop->toString() +
@@ -379,8 +382,8 @@ std::unordered_map<size_t, TokenStreamRewriter::RewriteOperation*> TokenStreamRe
379382
// whole token buffer so no lazy eval issue with any templates
380383
iop->text = catOpText(&iop->text, &prevIop->text);
381384
// delete redundant prior insert
382-
delete rewrites[prevIop->instructionIndex];
383385
rewrites[prevIop->instructionIndex] = nullptr;
386+
delete prevIop;
384387
}
385388
}
386389
// look for replaces where iop.index is in range; error

0 commit comments

Comments
 (0)