https://github.com/NuriAmari created https://github.com/llvm/llvm-project/pull/216075
When fix-its are emitted into a .dia, we previously stored the fix-it text in a blob of arbitrary size, but the size of the text was stored in a separate 16 bit field. For really large fix-its, the size won't fit it those 16 bits, and the compiler crashes. Switch to a variable length encoding of the fit-it size. This is similar to this issue: https://github.com/llvm/llvm-project/commit/e26aea5b290165f3bccffab662a706d4a56f7540 We also remove a hard coded check in the clang library used to load .dia files that failed for fix-its whose size doesn't fit in 16 bits. Generated with codex >From d7d2b46e72051aa5780f6e5d61e2a635318edba7 Mon Sep 17 00:00:00 2001 From: Nuri Amari <[email protected]> Date: Wed, 12 Aug 2026 13:51:18 -0700 Subject: [PATCH] [Frontend] Fix fix-it size overflow in emitted .dia When fix-its are emitted into a .dia, we previously stored the fix-it text in a blob of arbitrary size, but the size of the text was stored in a separate 16 bit field. For really large fix-its, the size won't fit it those 16 bits, and the compiler crashes. Switch to a variable length encoding of the fit-it size. This is similar to this issue: https://github.com/llvm/llvm-project/commit/e26aea5b290165f3bccffab662a706d4a56f7540 We also remove a hard coded check in the clang library used to load .dia files that failed for fix-its whose size doesn't fit in 16 bits. --- .../Frontend/SerializedDiagnosticPrinter.cpp | 2 +- .../test/Misc/serialized-diags-large-fixit.m | 45 +++++++++++++++++++ clang/tools/libclang/CXLoadedDiagnostic.cpp | 3 -- 3 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 clang/test/Misc/serialized-diags-large-fixit.m diff --git a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp index 58d080f5504c2..47585d43bb5e6 100644 --- a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp @@ -500,7 +500,7 @@ void SDiagsWriter::EmitBlockInfoBlock() { Abbrev = std::make_shared<BitCodeAbbrev>(); Abbrev->Add(BitCodeAbbrevOp(RECORD_FIXIT)); AddRangeLocationAbbrev(*Abbrev); - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Text size. + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // Text size. Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // FixIt text. Abbrevs.set(RECORD_FIXIT, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, Abbrev)); diff --git a/clang/test/Misc/serialized-diags-large-fixit.m b/clang/test/Misc/serialized-diags-large-fixit.m new file mode 100644 index 0000000000000..b2fb1fed07d00 --- /dev/null +++ b/clang/test/Misc/serialized-diags-large-fixit.m @@ -0,0 +1,45 @@ +// RUN: %clang -fsyntax-only -fobjc-runtime=macosx-10.8 \ +// RUN: -Wno-objc-root-class --serialize-diagnostics %t.dia %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=TEXT +// RUN: c-index-test -read-diagnostics %t.dia 2>&1 \ +// RUN: | FileCheck %s --check-prefix=SERIALIZED + +// Form an identifier larger than 64 KiB without making the test file enormous. +#define CAT_IMPL(A, B) A##B +#define CAT(A, B) CAT_IMPL(A, B) +#define A0 a +#define A1 CAT(A0, A0) +#define A2 CAT(A1, A1) +#define A3 CAT(A2, A2) +#define A4 CAT(A3, A3) +#define A5 CAT(A4, A4) +#define A6 CAT(A5, A5) +#define A7 CAT(A6, A6) +#define A8 CAT(A7, A7) +#define A9 CAT(A8, A8) +#define A10 CAT(A9, A9) +#define A11 CAT(A10, A10) +#define A12 CAT(A11, A11) +#define A13 CAT(A12, A12) +#define A14 CAT(A13, A13) +#define A15 CAT(A14, A14) +#define A16 CAT(A15, A15) +#define LARGE_IDENTIFIER CAT(A16, z) + +@protocol Protocol +@property int LARGE_IDENTIFIER; +@end + +@interface MyClass <Protocol> +@end + +@implementation MyClass +@end + +// TEXT: warning: auto property synthesis will not synthesize property +// TEXT: note: add a '@synthesize' directive +// SERIALIZED: warning: auto property synthesis will not synthesize property +// SERIALIZED: note: add a '@synthesize' directive +// SERIALIZED: FIXIT: +// SERIALIZED-SAME: z; +// SERIALIZED: Number of diagnostics: 1 diff --git a/clang/tools/libclang/CXLoadedDiagnostic.cpp b/clang/tools/libclang/CXLoadedDiagnostic.cpp index ed89a6a7754da..bfb02d4dcf49d 100644 --- a/clang/tools/libclang/CXLoadedDiagnostic.cpp +++ b/clang/tools/libclang/CXLoadedDiagnostic.cpp @@ -366,9 +366,6 @@ DiagLoader::visitFixitRecord(const serialized_diags::Location &Start, CXSourceRange SR; if (std::error_code EC = readRange(Start, End, SR)) return EC; - // FIXME: Why do we care about long strings? - if (CodeToInsert.size() > 65536) - return reportInvalidFile("Out-of-bounds string in FIXIT"); CurrentDiags.back()->FixIts.push_back( std::make_pair(SR, TopDiags->copyString(CodeToInsert))); return std::error_code(); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
