https://github.com/maxmanolov updated https://github.com/llvm/llvm-project/pull/205503
>From 268c083e3fa791cb184989f6a733a0f3580fee85 Mon Sep 17 00:00:00 2001 From: Max Manolov <[email protected]> Date: Wed, 24 Jun 2026 01:29:40 -0700 Subject: [PATCH] [clang][Sema] Avoid out-of-memory crash on huge designated initializer indices --- clang/docs/ReleaseNotes.md | 1 + clang/lib/Sema/SemaInit.cpp | 19 +++++++++++++++++++ clang/test/Sema/designated-initializers.c | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 09ec3594ab31f..58c81474e294c 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -720,6 +720,7 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the - Fixed an assertion where we improperly handled implicit conversions to integral types from an atomic-type with a conversion function. (#GH201770) - Fixed assertion failures involving code completion with delayed default arguments and exception specifications. (#GH200879) - Fixed a regression where calling a function that takes a class-type parameter by value inside `decltype` of a concept could be incorrectly rejected when used as a non-type template argument. (#GH175831) +- Clang now diagnoses inferred-size arrays with huge designated initializer indices instead of attempting to allocate an enormous initializer list and crashing with an out-of-memory error. (#GH205472) #### Bug Fixes to Compiler Builtins diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index dad9c8c972dd9..ba7aeac2dc9ee 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -39,6 +39,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +#include <limits> using namespace clang; @@ -3375,6 +3376,24 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, DesignatedEndIndex.setIsUnsigned(true); } + // The semantic form of an initializer list stores one pointer for every + // array element, including the elements omitted before a designator. Avoid + // creating an initializer list whose dense representation is too large for + // an unsigned-sized allocation. + constexpr unsigned MaxInitListElements = + std::numeric_limits<unsigned>::max() / sizeof(Stmt *); + if (DesignatedEndIndex.uge(MaxInitListElements)) { + if (!VerifyOnly) { + llvm::APSInt NumInits = + DesignatedEndIndex.extend(DesignatedEndIndex.getBitWidth() + 1); + ++NumInits; + SemaRef.Diag(IndexExpr->getBeginLoc(), diag::err_array_too_large) + << toString(NumInits, 10) << IndexExpr->getSourceRange(); + } + ++Index; + return true; + } + bool IsStringLiteralInitUpdate = StructuredList && StructuredList->isStringLiteralInit(); if (IsStringLiteralInitUpdate && VerifyOnly) { diff --git a/clang/test/Sema/designated-initializers.c b/clang/test/Sema/designated-initializers.c index 11dc3a2308dee..179b8855fe1c8 100644 --- a/clang/test/Sema/designated-initializers.c +++ b/clang/test/Sema/designated-initializers.c @@ -4,6 +4,25 @@ int complete_array_from_init[] = { 1, 2, [10] = 5, 1, 2, [5] = 2, 6 }; int complete_array_from_init_check[((sizeof(complete_array_from_init) / sizeof(int)) == 13)? 1 : -1]; +int normal_sparse_designated_initializer[] = { [3] = 1 }; +typedef char normal_sparse_designated_initializer_size[ + sizeof(normal_sparse_designated_initializer) / sizeof(int) == 4 ? 1 : -1]; + +struct LargeDesignatedInitializerPoint { + int x, y; +}; + +void large_designated_initializer(void) { + static struct LargeDesignatedInitializerPoint pts[] = { + [0x80000000] = { .x = 10, .y = 20 }, // expected-error {{array is too large (2147483649 elements)}} + [0x80000001] = { .x = 30, .y = 40 } // expected-error {{array is too large (2147483650 elements)}} + }; +} + +int large_fixed_designated_initializer[4] = { + [0x80000000] = 1, // expected-error {{array designator index (2147483648) exceeds array bounds (4)}} +}; + int iarray[10] = { [0] = 1, [1 ... 5] = 2, _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
