Skip to content

Commit 067e205

Browse files
authored
[clang][transformer] Change name range-selector to return Error instead of an invalid range. (#164715)
Previously, when the text in selected range was different from the decl's name, `name` returned an invalid range, which could cause crashes if `name` was nested in other range selectors that assumed always valid ranges. With this change, `name` returns an `Error` if it can't get the range.
1 parent e65d52a commit 067e205

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

clang/lib/Tooling/Transformer/RangeSelector.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,12 @@ RangeSelector transformer::name(std::string ID) {
205205
// `foo<int>` for which this range will be too short. Doing so will
206206
// require subcasing `NamedDecl`, because it doesn't provide virtual
207207
// access to the \c DeclarationNameInfo.
208-
if (tooling::getText(R, *Result.Context) != D->getName())
209-
return CharSourceRange();
208+
StringRef Text = tooling::getText(R, *Result.Context);
209+
if (Text != D->getName())
210+
return llvm::make_error<StringError>(
211+
llvm::errc::not_supported,
212+
"range selected by name(node id=" + ID + "): '" + Text +
213+
"' is different from decl name '" + D->getName() + "'");
210214
return R;
211215
}
212216
if (const auto *E = Node.get<DeclRefExpr>()) {

clang/unittests/Tooling/RangeSelectorTest.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,31 @@ TEST(RangeSelectorTest, NameOpDeclRefError) {
527527
AllOf(HasSubstr(Ref), HasSubstr("requires property 'identifier'")))));
528528
}
529529

530+
TEST(RangeSelectorTest, NameOpDeclInMacroArg) {
531+
StringRef Code = R"cc(
532+
#define MACRO(name) int name;
533+
MACRO(x)
534+
)cc";
535+
const char *ID = "id";
536+
TestMatch Match = matchCode(Code, varDecl().bind(ID));
537+
EXPECT_THAT_EXPECTED(select(name(ID), Match), HasValue("x"));
538+
}
539+
540+
TEST(RangeSelectorTest, NameOpDeclInMacroBodyError) {
541+
StringRef Code = R"cc(
542+
#define MACRO int x;
543+
MACRO
544+
)cc";
545+
const char *ID = "id";
546+
TestMatch Match = matchCode(Code, varDecl().bind(ID));
547+
EXPECT_THAT_EXPECTED(
548+
name(ID)(Match.Result),
549+
Failed<StringError>(testing::Property(
550+
&StringError::getMessage,
551+
AllOf(HasSubstr("range selected by name(node id="),
552+
HasSubstr("' is different from decl name 'x'")))));
553+
}
554+
530555
TEST(RangeSelectorTest, CallArgsOp) {
531556
const StringRef Code = R"cc(
532557
struct C {

0 commit comments

Comments
 (0)