https://github.com/and2049 created 
https://github.com/llvm/llvm-project/pull/224947

Skip brace insertion when the pair would enclose preprocessor directives, 
avoiding unmatched braces across conditional branches.
This also leaves bodies containing balanced directives unbraced, even where 
insertion previously produced valid code, consistent with the documented 
behavior.
Fixes #224942.


>From d033af06999bc4bd9d085a147c1fb3076abf13c2 Mon Sep 17 00:00:00 2001
From: Andre Sun <[email protected]>
Date: Sun, 20 Sep 2026 13:07:59 -0400
Subject: [PATCH] [clang-format] Fix InsertBraces inserting braces around
 directives

Fixes #224942.
---
 clang/lib/Format/UnwrappedLineParser.cpp      | 21 ++++++++-
 clang/unittests/Format/BracesInserterTest.cpp | 45 +++++++++++++++++++
 2 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index 2d2fe729fbc2f..86445cc02cfa6 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -2910,6 +2910,7 @@ void UnwrappedLineParser::parseUnbracedBody(bool 
CheckEOF) {
   }
 
   addUnwrappedLine();
+  const size_t BodyStart = CurrentLines->size();
   ++Line->Level;
   ++Line->UnbracedBodyLevel;
   parseStructuralElement();
@@ -2917,15 +2918,31 @@ void UnwrappedLineParser::parseUnbracedBody(bool 
CheckEOF) {
 
   if (Tok) {
     assert(!Line->InPPDirective);
+    FormatToken *const LBraceTok = Tok;
     Tok = nullptr;
-    for (const auto &L : llvm::reverse(*CurrentLines)) {
+    size_t BodyEnd = CurrentLines->size();
+    while (BodyEnd > 0) {
+      const auto &L = (*CurrentLines)[--BodyEnd];
       if (!L.InPPDirective && getLastNonComment(L)) {
         Tok = L.Tokens.back().Tok;
         break;
       }
     }
     assert(Tok);
-    ++Tok->BraceCount;
+    // Don't insert the braces if they would enclose preprocessor directives.
+    bool EnclosesPPDirective = false;
+    for (size_t I = BodyStart; I <= BodyEnd && !EnclosesPPDirective; ++I) {
+      const auto &L = (*CurrentLines)[I];
+      EnclosesPPDirective =
+          L.InPPDirective ||
+          llvm::any_of(L.Tokens, [](const UnwrappedLineNode &Node) {
+            return Node.Tok->FirstAfterPPLine;
+          });
+    }
+    if (EnclosesPPDirective)
+      LBraceTok->BraceCount = 0;
+    else
+      ++Tok->BraceCount;
   }
 
   if (CheckEOF && eof())
diff --git a/clang/unittests/Format/BracesInserterTest.cpp 
b/clang/unittests/Format/BracesInserterTest.cpp
index 572e53e595e37..11c7c17b9aeb4 100644
--- a/clang/unittests/Format/BracesInserterTest.cpp
+++ b/clang/unittests/Format/BracesInserterTest.cpp
@@ -195,6 +195,51 @@ TEST_F(BracesInserterTest, InsertBraces) {
                "#endif",
                Style);
 
+  verifyFormat("if (a)\n"
+               "  if (b)\n"
+               "#ifdef A\n"
+               "    f();\n"
+               "#else\n"
+               "    g();\n"
+               "#endif",
+               Style);
+
+  verifyFormat("while (a)\n"
+               "  if (b)\n"
+               "    f(\n"
+               "#ifdef A\n"
+               "        1);\n"
+               "#else\n"
+               "        2);\n"
+               "#endif",
+               Style);
+
+  verifyFormat("if (a)\n"
+               "  f(\n"
+               "#ifdef A\n"
+               "      1\n"
+               "#else\n"
+               "      2\n"
+               "#endif\n"
+               "  );",
+               Style);
+
+  verifyFormat("#if A\n"
+               "if (a) {\n"
+               "  f();\n"
+               "}\n"
+               "#else\n"
+               "if (b) {\n"
+               "  g();\n"
+               "}\n"
+               "#endif",
+               "#if A\n"
+               "if (a) f();\n"
+               "#else\n"
+               "if (b) g();\n"
+               "#endif",
+               Style);
+
   verifyFormat("#if 0\n"
                "#elif 1\n"
                "#endif\n"

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to