[clang] [clang-format] Fix a crash in EnumTrailingComma (PR #135903)
Owen Pan via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 16 20:56:12 PDT 2025
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/135903
>From 8f79ecf3e3f32b6b735a478eb1d3a48b7a6fa640 Mon Sep 17 00:00:00 2001
From: Owen Pan <owenpiano at gmail.com>
Date: Tue, 15 Apr 2025 21:02:28 -0700
Subject: [PATCH 1/2] [clang-format] Fix a crash in EnumTrailingComma
Fix #135819
---
clang/lib/Format/Format.cpp | 17 +++++++++++------
clang/unittests/Format/FormatTest.cpp | 11 +++++++++++
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index c601967a8715c..b8d55871ab932 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -2427,19 +2427,23 @@ class EnumTrailingCommaEditor : public TokenAnalyzer {
private:
void editEnumTrailingComma(SmallVectorImpl<AnnotatedLine *> &Lines,
tooling::Replacements &Result) {
+ bool InEnumBraces = false;
+ const FormatToken *BeforeRBrace = nullptr;
const auto &SourceMgr = Env.getSourceManager();
for (auto *Line : Lines) {
if (!Line->Children.empty())
editEnumTrailingComma(Line->Children, Result);
- if (!Line->Affected)
- continue;
for (const auto *Token = Line->First; Token && !Token->Finalized;
Token = Token->Next) {
- if (Token->isNot(TT_EnumRBrace))
+ if (Token->isNot(TT_EnumRBrace)) {
+ if (Token->is(TT_EnumLBrace))
+ InEnumBraces = true;
+ else if (InEnumBraces && Line->Affected && Token->isNot(tok::comment))
+ BeforeRBrace = Token;
continue;
- const auto *BeforeRBrace = Token->getPreviousNonComment();
- assert(BeforeRBrace);
- if (BeforeRBrace->is(TT_EnumLBrace)) // Empty braces.
+ }
+ InEnumBraces = false;
+ if (!BeforeRBrace) // Empty braces or Line not affected.
continue;
if (BeforeRBrace->is(tok::comma)) {
if (Style.EnumTrailingComma == FormatStyle::ETC_Remove)
@@ -2448,6 +2452,7 @@ class EnumTrailingCommaEditor : public TokenAnalyzer {
cantFail(Result.add(tooling::Replacement(
SourceMgr, BeforeRBrace->Tok.getEndLoc(), 0, ",")));
}
+ BeforeRBrace = nullptr;
}
}
}
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index b62d49e17c83f..be0343efb4b83 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -27962,6 +27962,7 @@ TEST_F(FormatTest, EnumTrailingComma) {
verifyFormat(Code);
auto Style = getLLVMStyle();
+ EXPECT_TRUE(Style.AllowShortEnumsOnASingleLine);
Style.EnumTrailingComma = FormatStyle::ETC_Insert;
verifyFormat("enum : int { /**/ };\n"
"enum {\n"
@@ -27972,6 +27973,16 @@ TEST_F(FormatTest, EnumTrailingComma) {
"enum Color { red, green, blue, /**/ };",
Code, Style);
+ Style.AllowShortEnumsOnASingleLine = false;
+ verifyFormat("enum class MyEnum_E {\n"
+ " MY_ENUM = 0U,\n"
+ "};",
+ "enum class MyEnum_E {\n"
+ " MY_ENUM = 0U\n"
+ "};",
+ Style);
+ Style.AllowShortEnumsOnASingleLine = true;
+
Style.EnumTrailingComma = FormatStyle::ETC_Remove;
verifyFormat("enum : int { /**/ };\n"
"enum {\n"
>From 7e8e7b9ad6a834752af08717891c3066dca66b34 Mon Sep 17 00:00:00 2001
From: Owen Pan <owenpiano at gmail.com>
Date: Wed, 16 Apr 2025 20:55:18 -0700
Subject: [PATCH 2/2] Fix a bug in range formatting
---
clang/lib/Format/Format.cpp | 4 +--
clang/unittests/Format/FormatTest.cpp | 38 +++++++++++++++++++--------
2 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index b8d55871ab932..0667813110454 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -2438,8 +2438,8 @@ class EnumTrailingCommaEditor : public TokenAnalyzer {
if (Token->isNot(TT_EnumRBrace)) {
if (Token->is(TT_EnumLBrace))
InEnumBraces = true;
- else if (InEnumBraces && Line->Affected && Token->isNot(tok::comment))
- BeforeRBrace = Token;
+ else if (InEnumBraces && Token->isNot(tok::comment))
+ BeforeRBrace = Line->Affected ? Token : nullptr;
continue;
}
InEnumBraces = false;
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index be0343efb4b83..fc544b946cf44 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -27962,7 +27962,6 @@ TEST_F(FormatTest, EnumTrailingComma) {
verifyFormat(Code);
auto Style = getLLVMStyle();
- EXPECT_TRUE(Style.AllowShortEnumsOnASingleLine);
Style.EnumTrailingComma = FormatStyle::ETC_Insert;
verifyFormat("enum : int { /**/ };\n"
"enum {\n"
@@ -27973,16 +27972,6 @@ TEST_F(FormatTest, EnumTrailingComma) {
"enum Color { red, green, blue, /**/ };",
Code, Style);
- Style.AllowShortEnumsOnASingleLine = false;
- verifyFormat("enum class MyEnum_E {\n"
- " MY_ENUM = 0U,\n"
- "};",
- "enum class MyEnum_E {\n"
- " MY_ENUM = 0U\n"
- "};",
- Style);
- Style.AllowShortEnumsOnASingleLine = true;
-
Style.EnumTrailingComma = FormatStyle::ETC_Remove;
verifyFormat("enum : int { /**/ };\n"
"enum {\n"
@@ -27992,6 +27981,33 @@ TEST_F(FormatTest, EnumTrailingComma) {
"};\n"
"enum Color { red, green, blue /**/ };",
Code, Style);
+
+ EXPECT_TRUE(Style.AllowShortEnumsOnASingleLine);
+ Style.AllowShortEnumsOnASingleLine = false;
+
+ constexpr StringRef Input("enum {\n"
+ " //\n"
+ " a,\n"
+ " /**/\n"
+ " b,\n"
+ "};");
+ verifyFormat(Input, Input, Style, {tooling::Range(12, 3)}); // line 3
+ verifyFormat("enum {\n"
+ " //\n"
+ " a,\n"
+ " /**/\n"
+ " b\n"
+ "};",
+ Input, Style, {tooling::Range(24, 3)}); // line 5
+
+ Style.EnumTrailingComma = FormatStyle::ETC_Insert;
+ verifyFormat("enum class MyEnum_E {\n"
+ " MY_ENUM = 0U,\n"
+ "};",
+ "enum class MyEnum_E {\n"
+ " MY_ENUM = 0U\n"
+ "};",
+ Style);
}
TEST_F(FormatTest, BreakAfterAttributes) {
More information about the cfe-commits
mailing list