[clang] [clang][transformer] Change `name` range-selector to return `Error` instead of an invalid range. (PR #164715)
Florian Mayer via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 30 12:25:02 PDT 2025
https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/164715
>From 57dd8a94c08351605823acfe874f94819d19bad0 Mon Sep 17 00:00:00 2001
From: Yu Hao <yuhaoyu at google.com>
Date: Wed, 22 Oct 2025 15:00:12 -0700
Subject: [PATCH] [clang][transformer] Change `name` range-selector to return
`Error` instead of an invalid range.
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.
---
.../lib/Tooling/Transformer/RangeSelector.cpp | 8 ++++--
clang/unittests/Tooling/RangeSelectorTest.cpp | 25 +++++++++++++++++++
2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Tooling/Transformer/RangeSelector.cpp b/clang/lib/Tooling/Transformer/RangeSelector.cpp
index 171c786bc366f..b4bdec1fcdd69 100644
--- a/clang/lib/Tooling/Transformer/RangeSelector.cpp
+++ b/clang/lib/Tooling/Transformer/RangeSelector.cpp
@@ -205,8 +205,12 @@ RangeSelector transformer::name(std::string ID) {
// `foo<int>` for which this range will be too short. Doing so will
// require subcasing `NamedDecl`, because it doesn't provide virtual
// access to the \c DeclarationNameInfo.
- if (tooling::getText(R, *Result.Context) != D->getName())
- return CharSourceRange();
+ StringRef Text = tooling::getText(R, *Result.Context);
+ if (Text != D->getName())
+ return llvm::make_error<StringError>(
+ llvm::errc::not_supported,
+ "range selected by name(node id=" + ID + "): '" + Text +
+ "' is different from decl name '" + D->getName() + "'");
return R;
}
if (const auto *E = Node.get<DeclRefExpr>()) {
diff --git a/clang/unittests/Tooling/RangeSelectorTest.cpp b/clang/unittests/Tooling/RangeSelectorTest.cpp
index adf5e74ea3192..a1fcbb023832f 100644
--- a/clang/unittests/Tooling/RangeSelectorTest.cpp
+++ b/clang/unittests/Tooling/RangeSelectorTest.cpp
@@ -527,6 +527,31 @@ TEST(RangeSelectorTest, NameOpDeclRefError) {
AllOf(HasSubstr(Ref), HasSubstr("requires property 'identifier'")))));
}
+TEST(RangeSelectorTest, NameOpDeclInMacroArg) {
+ StringRef Code = R"cc(
+ #define MACRO(name) int name;
+ MACRO(x)
+ )cc";
+ const char *ID = "id";
+ TestMatch Match = matchCode(Code, varDecl().bind(ID));
+ EXPECT_THAT_EXPECTED(select(name(ID), Match), HasValue("x"));
+}
+
+TEST(RangeSelectorTest, NameOpDeclInMacroBodyError) {
+ StringRef Code = R"cc(
+ #define MACRO int x;
+ MACRO
+ )cc";
+ const char *ID = "id";
+ TestMatch Match = matchCode(Code, varDecl().bind(ID));
+ EXPECT_THAT_EXPECTED(
+ name(ID)(Match.Result),
+ Failed<StringError>(testing::Property(
+ &StringError::getMessage,
+ AllOf(HasSubstr("range selected by name(node id="),
+ HasSubstr("' is different from decl name 'x'")))));
+}
+
TEST(RangeSelectorTest, CallArgsOp) {
const StringRef Code = R"cc(
struct C {
More information about the cfe-commits
mailing list