[clang] [clang-format] Avoid crashing on malformed template closers in mustBreak (PR #173453)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 23 21:50:08 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-format
Author: Dillon Amburgey (dillona)
<details>
<summary>Changes</summary>
If a template closer has no MatchingParen, return false instead of asserting so malformed enable_if declarations don’t force a break.
Fixes: https://github.com/llvm/llvm-project/issues/173382
---
Full diff: https://github.com/llvm/llvm-project/pull/173453.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+3)
- (modified) clang/lib/Format/ContinuationIndenter.cpp (+2-1)
- (modified) clang/unittests/Format/FormatTest.cpp (+16)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2319ff13f7864..3dc1698616ff3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -793,6 +793,9 @@ clang-format
- Rename ``(Binary|Decimal|Hex)MinDigits`` to ``...MinDigitsInsert`` and add
``(Binary|Decimal|Hex)MaxDigitsSeparator`` suboptions to
``IntegerLiteralSeparator``.
+- Avoid crashing when formatting malformed template code that lacks a matching
+ template closer (e.g., broken ``enable_if`` declarations) by bailing out
+ instead of asserting. (#GH173382)
libclang
--------
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 1272bb72d423f..30f7278946fa9 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -675,7 +675,8 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
return false;
if (Tok->is(TT_TemplateCloser)) {
Tok = Tok->MatchingParen;
- assert(Tok);
+ if (!Tok)
+ return false; // Bail out on malformed template structure.
}
if (Tok->FirstAfterPPLine)
return false;
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 5cdac66d1dcbd..ecc184cb3b79f 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15421,6 +15421,22 @@ TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) {
verifyFormat("class A:");
}
+TEST_F(FormatTest, DoesNotCrashOnMalformedEnableIf) {
+ const char *Code =
+ "template <typename T, typename TIString>\n"
+ "typename etl::enable_if<etl::is_integral<T>::value &&\n"
+ " !etl::is_same<T, bool>::value>::value,\n"
+ " const TIString& > ::type\n"
+ "to_string(const T value, TIString& str,\n"
+ " const etl::basic_format_spec<TIString>& format,\n"
+ " const bool append = false) {\n"
+ "}\n";
+ // Ensure formatting malformed template syntax doesn't assert, regardless of
+ // whether clang-format considers the input complete.
+ EXPECT_NO_FATAL_FAILURE(format(Code, std::nullopt, SC_DoNotCheck));
+ EXPECT_NO_FATAL_FAILURE(format(messUp(Code), std::nullopt, SC_DoNotCheck));
+}
+
TEST_F(FormatTest, DoNotInterfereWithErrorAndWarning) {
verifyNoChange("#error Leave all white!!!!! space* alone!");
verifyNoChange("#warning Leave all white!!!!! space* alone!");
``````````
</details>
https://github.com/llvm/llvm-project/pull/173453
More information about the cfe-commits
mailing list