This is an archive of the discontinued LLVM Phabricator instance.

[clang][Rewriter] patch to fix bug with ReplaceText erasing too many characters when text has been inserted before the replace location.
Needs ReviewPublic

Authored by ajohnson-uoregon on Aug 4 2021, 2:52 PM.

Details

Summary

See https://llvm.discourse.group/t/possible-bug-in-clang-rewriter-clang-rewritebuffer-and-or-clang-rewriterope/3970 for initial explanation of bug.

[clang][Rewriter] split test for replace after insert to be more understandable and also a fix to make the test correct

Diff Detail

Event Timeline

ajohnson-uoregon requested review of this revision.Aug 4 2021, 2:52 PM
ajohnson-uoregon created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptAug 4 2021, 2:52 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
ajohnson-uoregon retitled this revision from [clang][Rewriter] patch to fix bug with ReplaceText erasing too many characters when text has been inserted before the replace location. See https://llvm.discourse.group/t/possible-bug-in-clang-rewriter-clang-rewritebuffer-and-or-clang... to [clang][Rewriter] patch to fix bug with ReplaceText erasing too many characters when text has been inserted before the replace location. .Aug 4 2021, 3:01 PM
ajohnson-uoregon edited the summary of this revision. (Show Details)
ajohnson-uoregon retitled this revision from [clang][Rewriter] patch to fix bug with ReplaceText erasing too many characters when text has been inserted before the replace location. to [clang][Rewriter] patch to fix bug with ReplaceText erasing too many characters when text has been inserted before the replace location..

Making clang-format happy

making patch happy???

jdenny added a comment.EditedAug 17 2021, 4:23 PM

Thanks for working on this. I agree there's a bug. However, this patch doesn't fix the bug. It provides a workaround.

That is, the current default ReplaceText behavior, as revealed in the first test added by this patch, doesn't make sense. IncludeInsertsAtBeginOfRange=true (the default) should mean to also remove the text that was previously inserted before the specified range. Instead, the previously inserted text confuses the implementation, so it removes extra text after the specified range. It's hard to imagine anyone is relying on that broken behavior.

I see a couple of potential paths forward. Either:

  1. Change the patch summary and the new comments to make it clear that the default behavior is broken, so specifying IncludeInsertsAtBeginOfRange=false is the only way to ensure reasonable behavior. FIXME: should prefix some of those comments.
  1. Fix the bug. I've added an inline comment to suggest a possible fix, but I haven't tested it carefully.

Either way, RemoveText should be addressed in the same manner as it has the same bug.

clang/lib/Rewrite/Rewriter.cpp
132

I think this might fix the bug, but I haven't tested thoroughly.

One problem is ensuring backward compatibility here and in callers while keeping a consistent interface. That is, the previous default here was IncludeInsertsAtBeginOfRange=false, but it seems the intended default elsewhere is meant to be the opposite.

jdenny added inline comments.Aug 17 2021, 7:48 PM
clang/lib/Rewrite/Rewriter.cpp
136

I think this needs to be fixed too. That is, the removal of the inserts requires updating the insert delta separately from the replace delta. Otherwise, a future getRewrittenText ending at OrigOffset will include extra characters.