https://github.com/tJener created https://github.com/llvm/llvm-project/pull/146761
Before this commit, when `LineJoiner` joins a line with affected leading whitespace, it would drop the knowledge of this entirely. However, when the `AffectedRangeManager` is computing the affected lines, the leading empty whitespace lines are potentially considered for non-first tokens in the `AnnotatedLine`. This causes a discrepancy in behavior when an `AnnotatedLine` is put together from joining multiple lines versus when it is not. We change `LineJoiner::join` to follow `AffectedRangeManager`'s logic, considering the leading whitespace when determining `Affected` for a token if the previous token did not have children. https://github.com/llvm/llvm-project/blob/a63f57262898588b576d66e5fd79c0aa64b35f2d/clang/lib/Format/AffectedRangeManager.cpp#L111-L130 Fixes #138942. >From 61e2f8e1d79563ad9bd9478e97ee1d597518f305 Mon Sep 17 00:00:00 2001 From: Eric Li <li.zhe....@gmail.com> Date: Wed, 2 Jul 2025 14:46:45 -0400 Subject: [PATCH] [clang-format] Propagate `LeadingEmptyLinesAffected` when joining lines Before this commit, when `LineJoiner` joins a line with affected leading whitespace, it would drop the knowledge of this entirely. However, when the `AffectedRangeManager` is computing the affected lines, the leading empty whitespace lines are potentially considered for non-first tokens in the `AnnotatedLine`. This causes a discrepancy in behavior when an `AnnotatedLine` is put together from joining multiple lines versus when it is not. We change `LineJoiner::join` to follow `AffectedRangeManager`'s logic, considering the leading whitespace when determining `Affected` for a token if the previous token did not have children. https://github.com/llvm/llvm-project/blob/a63f57262898588b576d66e5fd79c0aa64b35f2d/clang/lib/Format/AffectedRangeManager.cpp#L111-L130 Fixes #138942. --- clang/lib/Format/UnwrappedLineFormatter.cpp | 2 ++ clang/unittests/Format/FormatTestSelective.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index f2ed027b2c047..d22bfc61ed736 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -988,6 +988,8 @@ class LineJoiner { assert(!B.First->Previous); if (B.Affected) A.Affected = true; + else if (B.LeadingEmptyLinesAffected && A.Last->Children.empty()) + A.Affected = true; A.Last->Next = B.First; B.First->Previous = A.Last; B.First->CanBreakBefore = true; diff --git a/clang/unittests/Format/FormatTestSelective.cpp b/clang/unittests/Format/FormatTestSelective.cpp index 624684c7a079b..3500b7d47e99d 100644 --- a/clang/unittests/Format/FormatTestSelective.cpp +++ b/clang/unittests/Format/FormatTestSelective.cpp @@ -41,6 +41,8 @@ TEST_F(FormatTestSelective, RemovesTrailingWhitespaceOfFormattedLine) { EXPECT_EQ("int a;", format("int a; ", 0, 0)); EXPECT_EQ("int a;\n", format("int a; \n \n \n ", 0, 0)); EXPECT_EQ("int a;\nint b; ", format("int a; \nint b; ", 0, 0)); + + EXPECT_EQ("void f() {}\n", format("void f() {\n \n}\n", 11, 0)); } TEST_F(FormatTestSelective, FormatsCorrectRegionForLeadingWhitespace) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits