-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[clang][Tooling] Fix getFileRange returning a range spanning across macro arguments
#169757
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-clang Author: Eric Li (tJener) ChangesWhen the start and end token are both spelled in macro arguments, we still want to reject the range if they come from two separate macro arguments, as the original specified range is not precisely spelled in a single sequence of characters in source. Full diff: https://github.com/llvm/llvm-project/pull/169757.diff 2 Files Affected:
diff --git a/clang/lib/Tooling/Transformer/SourceCode.cpp b/clang/lib/Tooling/Transformer/SourceCode.cpp
index 922dafeddf416..fa9bf3427b8a0 100644
--- a/clang/lib/Tooling/Transformer/SourceCode.cpp
+++ b/clang/lib/Tooling/Transformer/SourceCode.cpp
@@ -86,8 +86,12 @@ llvm::Error clang::tooling::validateEditRange(const CharSourceRange &Range,
return validateRange(Range, SM, /*AllowSystemHeaders=*/false);
}
-static bool spelledInMacroDefinition(SourceLocation Loc,
- const SourceManager &SM) {
+// Returns the location of the top-level macro argument that is the spelling for
+// the expansion `Loc` is from. If `Loc` is spelled in the macro definition,
+// returns an invalid `SourceLocation`.
+static SourceLocation getMacroArgumentSpellingLoc(SourceLocation Loc,
+ const SourceManager &SM) {
+ assert(Loc.isMacroID() && "Location must be in a macro");
while (Loc.isMacroID()) {
const auto &Expansion = SM.getSLocEntry(SM.getFileID(Loc)).getExpansion();
if (Expansion.isMacroArgExpansion()) {
@@ -95,9 +99,26 @@ static bool spelledInMacroDefinition(SourceLocation Loc,
// in a macro expansion.
Loc = Expansion.getSpellingLoc();
} else {
- return true;
+ return {};
}
}
+ return Loc;
+}
+
+static bool spelledInMacroDefinition(CharSourceRange Range,
+ const SourceManager &SM) {
+ if (Range.getBegin().isMacroID() && Range.getEnd().isMacroID()) {
+ // Check whether the range is entirely within a single macro argument.
+ auto B = getMacroArgumentSpellingLoc(Range.getBegin(), SM);
+ auto E = getMacroArgumentSpellingLoc(Range.getEnd(), SM);
+ return B.isInvalid() || B != E;
+ }
+
+ if (Range.getBegin().isMacroID())
+ return getMacroArgumentSpellingLoc(Range.getBegin(), SM).isInvalid();
+ if (Range.getEnd().isMacroID())
+ return getMacroArgumentSpellingLoc(Range.getEnd(), SM).isInvalid();
+
return false;
}
@@ -158,8 +179,7 @@ static CharSourceRange getRange(const CharSourceRange &EditRange,
Range = Lexer::makeFileCharRange(EditRange, SM, LangOpts);
} else {
auto AdjustedRange = getRangeForSplitTokens(EditRange, SM, LangOpts);
- if (spelledInMacroDefinition(AdjustedRange.getBegin(), SM) ||
- spelledInMacroDefinition(AdjustedRange.getEnd(), SM))
+ if (spelledInMacroDefinition(AdjustedRange, SM))
return {};
auto B = SM.getSpellingLoc(AdjustedRange.getBegin());
diff --git a/clang/unittests/Tooling/SourceCodeTest.cpp b/clang/unittests/Tooling/SourceCodeTest.cpp
index 549b77752f1c2..4932e0bd9431b 100644
--- a/clang/unittests/Tooling/SourceCodeTest.cpp
+++ b/clang/unittests/Tooling/SourceCodeTest.cpp
@@ -510,10 +510,12 @@ TEST(SourceCodeTest, EditInvolvingExpansionIgnoringExpansionShouldFail) {
#define M1(x) x(1)
#define M2(x, y) x ## y
#define M3(x) foobar(x)
+#define M4(x, y) x y
int foobar(int);
int a = M1(foobar);
int b = M2(foo, bar(2));
int c = M3(3);
+int d = M4(foobar, (2));
)cpp");
CallsVisitor Visitor;
|
… macro arguments When the start and end token are both spelled in macro arguments, we still want to reject the range if they come from two separate macro arguments, as the original specified range is not precisely spelled in a single sequence of characters in source.
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/88/builds/18515 Here is the relevant piece of the build log for the reference |
… macro arguments (llvm#169757) When the start and end token are both spelled in macro arguments, we still want to reject the range if they come from two separate macro arguments, as the original specified range is not precisely spelled in a single sequence of characters in source.
|
Had not realized that auto-merge would merge once tests finished running; I had assumed it'd be triggered by reviewer LGTM. That said, if you have any comments I can address them in a separate commit. |
When the start and end token are both spelled in macro arguments, we still want to reject the range if they come from two separate macro arguments, as the original specified range is not precisely spelled in a single sequence of characters in source.