[clang-tools-extra] [clangd] Do not offer extraction to variable for decl init expression (PR #69477)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 18 08:50:33 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangd
Author: None (ckandeler)
<details>
<summary>Changes</summary>
That would turn:
int x = f() + 1;
into:
auto placeholder = f() + 1;
int x = placeholder;
which makes little sense and is clearly not intended, as stated explicitly by a comment in eligibleForExtraction(). It appears that the declaration case was simply forgotten (the assignment case was already implemented).
---
Full diff: https://github.com/llvm/llvm-project/pull/69477.diff
2 Files Affected:
- (modified) clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp (+9-1)
- (modified) clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp (+3-67)
``````````diff
diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp
index 1e4edc6d6b4bb39..26fa94ded1f012e 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp
@@ -467,7 +467,8 @@ bool eligibleForExtraction(const SelectionTree::Node *N) {
// Extracting Exprs like a = 1 gives placeholder = a = 1 which isn't useful.
// FIXME: we could still hoist the assignment, and leave the variable there?
ParsedBinaryOperator BinOp;
- if (BinOp.parse(*N) && BinaryOperator::isAssignmentOp(BinOp.Kind))
+ bool IsBinOp = BinOp.parse(*N);
+ if (IsBinOp && BinaryOperator::isAssignmentOp(BinOp.Kind))
return false;
const SelectionTree::Node &OuterImplicit = N->outerImplicit();
@@ -490,6 +491,13 @@ bool eligibleForExtraction(const SelectionTree::Node *N) {
BO->getRHS() == OuterImplicit.ASTNode.get<Expr>())
return false;
}
+ if (const auto *Decl = Parent->ASTNode.get<VarDecl>()) {
+ if (!Decl->isInitCapture() &&
+ Decl->getInit() == OuterImplicit.ASTNode.get<Expr>() &&
+ (!IsBinOp || !BinOp.associative())) {
+ return false;
+ }
+ }
return true;
}
diff --git a/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp
index 3d74a941071f849..7ca717747e49a7b 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp
@@ -27,10 +27,10 @@ TEST_F(ExtractVariableTest, Test) {
return [[[[t.b[[a]]r]]([[t.z]])]];
}
void f() {
- int a = [[5 +]] [[4 * [[[[xyz]]()]]]];
+ int a = 5 + [[4 * [[[[xyz]]()]]]];
// multivariable initialization
if(1)
- int x = [[1]], y = [[a + 1]], a = [[1]], z = a + 1;
+ int x = [[1]] + 1, y = [[a + 1]], a = [[1]] + 2, z = a + 1;
// if without else
if([[1]])
a = [[1]] + 1;
@@ -61,7 +61,7 @@ TEST_F(ExtractVariableTest, Test) {
ExtraArgs = {"-xc"};
const char *AvailableC = R"cpp(
void foo() {
- int x = [[1]];
+ int x = [[1]] + 1;
})cpp";
EXPECT_AVAILABLE(AvailableC);
ExtraArgs = {"-xobjective-c"};
@@ -422,8 +422,6 @@ TEST_F(ExtractVariableTest, Test) {
int member = 42;
};
)cpp"},
- {R"cpp(void f() { auto x = [[ [](){ return 42; }]]; })cpp",
- R"cpp(void f() { auto placeholder = [](){ return 42; }; auto x = placeholder; })cpp"},
{R"cpp(
template <typename T>
auto sink(T f) { return f(); }
@@ -504,68 +502,6 @@ TEST_F(ExtractVariableTest, Test) {
int main() {
auto placeholder = []() { return 42; }(); return placeholder ;
})cpp"},
- {R"cpp(
- template <typename ...Ts>
- void foo(Ts ...args) {
- auto x = [[ [&args...]() {} ]];
- }
- )cpp",
- R"cpp(
- template <typename ...Ts>
- void foo(Ts ...args) {
- auto placeholder = [&args...]() {}; auto x = placeholder ;
- }
- )cpp"},
- {R"cpp(
- struct Coordinates {
- int x{};
- int y{};
- };
-
- int main() {
- Coordinates c = {};
- const auto [x, y] = c;
- auto f = [[ [&]() { return x + y; } ]];
- }
- )cpp",
- R"cpp(
- struct Coordinates {
- int x{};
- int y{};
- };
-
- int main() {
- Coordinates c = {};
- const auto [x, y] = c;
- auto placeholder = [&]() { return x + y; }; auto f = placeholder ;
- }
- )cpp"},
- {R"cpp(
- struct Coordinates {
- int x{};
- int y{};
- };
-
- int main() {
- Coordinates c = {};
- if (const auto [x, y] = c; x > y) {
- auto f = [[ [&]() { return x + y; } ]];
- }
- }
- )cpp",
- R"cpp(
- struct Coordinates {
- int x{};
- int y{};
- };
-
- int main() {
- Coordinates c = {};
- if (const auto [x, y] = c; x > y) {
- auto placeholder = [&]() { return x + y; }; auto f = placeholder ;
- }
- }
- )cpp"},
// Don't try to analyze across macro boundaries
// FIXME: it'd be nice to do this someday (in a safe way)
{R"cpp(#define ECHO(X) X
``````````
</details>
https://github.com/llvm/llvm-project/pull/69477
More information about the cfe-commits
mailing list