https://github.com/tobiichi3227 updated https://github.com/llvm/llvm-project/pull/192471
>From 87c582d31dd064561f9bd25de211cda6bafd5f5f Mon Sep 17 00:00:00 2001 From: tobiichi3227 <[email protected]> Date: Thu, 16 Apr 2026 22:43:04 +0800 Subject: [PATCH 1/6] [clang][Sema] Fix crash when checking scalar type with excess braces `InitListChecker::CheckScalarType()` crashed with multiple nested braces in scalar initializers (e.g., `int v = {{}, {}, {}};`) due to out-of-bounds access when retrieving diagnostic location from uninitialized StructuredList. Add bounds checking before `getInit(0)` access and add regression test --- clang/lib/Sema/SemaInit.cpp | 17 +++++++++++------ clang/test/Sema/init.c | 3 +++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 09d9f1eabd058..5a097dcb2c3b1 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -1362,26 +1362,32 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity, // Don't complain for incomplete types, since we'll get an error elsewhere. if ((Index < IList->getNumInits() || CurEmbed) && !T->isIncompleteType()) { // We have leftover initializers + Expr *ExtraInit = Index < IList->getNumInits() ? IList->getInit(Index) + : CurEmbed; + SourceLocation ExtraInitLoc = + ExtraInit ? ExtraInit->getBeginLoc() : IList->getEndLoc(); + SourceRange ExtraInitRange = + ExtraInit ? ExtraInit->getSourceRange() : IList->getSourceRange(); bool ExtraInitsIsError = SemaRef.getLangOpts().CPlusPlus || (SemaRef.getLangOpts().OpenCL && T->isVectorType()); hadError = ExtraInitsIsError; if (VerifyOnly) { return; } else if (StructuredIndex == 1 && + StructuredList->getNumInits() != 0 && + StructuredList->getInit(0) && IsStringInit(StructuredList->getInit(0), T, SemaRef.Context) == SIF_None) { unsigned DK = ExtraInitsIsError ? diag::err_excess_initializers_in_char_array_initializer : diag::ext_excess_initializers_in_char_array_initializer; - SemaRef.Diag(IList->getInit(Index)->getBeginLoc(), DK) - << IList->getInit(Index)->getSourceRange(); + SemaRef.Diag(ExtraInitLoc, DK) << ExtraInitRange; } else if (T->isSizelessBuiltinType()) { unsigned DK = ExtraInitsIsError ? diag::err_excess_initializers_for_sizeless_type : diag::ext_excess_initializers_for_sizeless_type; - SemaRef.Diag(IList->getInit(Index)->getBeginLoc(), DK) - << T << IList->getInit(Index)->getSourceRange(); + SemaRef.Diag(ExtraInitLoc, DK) << T << ExtraInitRange; } else { int initKind = T->isArrayType() ? 0 : T->isVectorType() ? 1 @@ -1392,8 +1398,7 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity, unsigned DK = ExtraInitsIsError ? diag::err_excess_initializers : diag::ext_excess_initializers; - SemaRef.Diag(IList->getInit(Index)->getBeginLoc(), DK) - << initKind << IList->getInit(Index)->getSourceRange(); + SemaRef.Diag(ExtraInitLoc, DK) << initKind << ExtraInitRange; } } diff --git a/clang/test/Sema/init.c b/clang/test/Sema/init.c index cf3788bc21c93..2c544b7fdd0e2 100644 --- a/clang/test/Sema/init.c +++ b/clang/test/Sema/init.c @@ -204,3 +204,6 @@ union PR4517_u { const union PR4517_u u1 = {4.0f}; const union PR4517_u u2 = u1; // no-warning const union PR4517_u u3 = {u1.y}; // expected-error {{initializer element is not a compile-time constant}} + +int PR192471_1 = {{}, {}, {}}; // expected-warning {{too many braces around scalar initializer}} expected-warning {{excess elements in scalar initializer}} +char PR192471_2 = {"1110", "3227"}; // expected-warning {{excess elements in char array initializer}} \ No newline at end of file >From 5656b1290dc084e05bc0db05995c702d7591d391 Mon Sep 17 00:00:00 2001 From: tobiichi3227 <[email protected]> Date: Fri, 1 May 2026 02:36:33 +0800 Subject: [PATCH 2/6] Remove unnecessary test --- clang/test/Sema/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Sema/init.c b/clang/test/Sema/init.c index 2c544b7fdd0e2..e26787d573086 100644 --- a/clang/test/Sema/init.c +++ b/clang/test/Sema/init.c @@ -206,4 +206,4 @@ const union PR4517_u u2 = u1; // no-warning const union PR4517_u u3 = {u1.y}; // expected-error {{initializer element is not a compile-time constant}} int PR192471_1 = {{}, {}, {}}; // expected-warning {{too many braces around scalar initializer}} expected-warning {{excess elements in scalar initializer}} -char PR192471_2 = {"1110", "3227"}; // expected-warning {{excess elements in char array initializer}} \ No newline at end of file + >From c85aa30711bb2fdebceec160faa4aac6d83b7599 Mon Sep 17 00:00:00 2001 From: tobiichi3227 <[email protected]> Date: Sat, 2 May 2026 10:35:35 +0800 Subject: [PATCH 3/6] Add more test about #embed --- clang/test/Sema/init.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/clang/test/Sema/init.c b/clang/test/Sema/init.c index e26787d573086..13f92c87ccf63 100644 --- a/clang/test/Sema/init.c +++ b/clang/test/Sema/init.c @@ -206,4 +206,12 @@ const union PR4517_u u2 = u1; // no-warning const union PR4517_u u3 = {u1.y}; // expected-error {{initializer element is not a compile-time constant}} int PR192471_1 = {{}, {}, {}}; // expected-warning {{too many braces around scalar initializer}} expected-warning {{excess elements in scalar initializer}} +char PR192471_2[] = { + "1110", +#embed __FILE__ +}; // expected-warning {{excess elements in char array initializer}} +char PR192471_3[1] = { +#embed __FILE__ limit(1) +, 49, 49, 49, 48 +}; // expected-warning {{excess elements in array initializer}} >From 336a5c3e3afcc1c768e48f8f82af7206d435dc85 Mon Sep 17 00:00:00 2001 From: tobiichi3227 <[email protected]> Date: Thu, 30 Jul 2026 14:03:54 +0800 Subject: [PATCH 4/6] Add more regression tests from gh issue Fix #137845, #69213, #198767, #207566, #106180 --- clang/test/Sema/init.c | 46 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/clang/test/Sema/init.c b/clang/test/Sema/init.c index 13f92c87ccf63..0f333ee309d9d 100644 --- a/clang/test/Sema/init.c +++ b/clang/test/Sema/init.c @@ -208,10 +208,46 @@ const union PR4517_u u3 = {u1.y}; // expected-error {{initializer element is not int PR192471_1 = {{}, {}, {}}; // expected-warning {{too many braces around scalar initializer}} expected-warning {{excess elements in scalar initializer}} char PR192471_2[] = { "1110", -#embed __FILE__ -}; // expected-warning {{excess elements in char array initializer}} +#embed __FILE__ // expected-warning {{#embed is a C23 extension}} \ + expected-warning {{excess elements in char array initializer}} +}; char PR192471_3[1] = { -#embed __FILE__ limit(1) -, 49, 49, 49, 48 -}; // expected-warning {{excess elements in array initializer}} +#embed __FILE__ limit(1) // expected-warning {{#embed is a C23 extension}} +, 49, 49, 49, 48 // expected-warning {{excess elements in array initializer}} +}; + +// GH137845 +struct GH137845_Data; // expected-note 2 {{forward declaration of 'struct GH137845_Data'}} +double GH137845_swap(struct GH137845_Data *, struct GH137845_Data *); +void GH137845(void) { + GH137845_swap( + (struct GH137845_Data[5]){{}, 1}, // expected-error {{array has incomplete element type 'struct GH137845_Data'}} \ + expected-warning {{too many braces around scalar initializer}} \ + expected-warning {{excess elements in scalar initializer}} + (struct GH137845_Data[5]){{}, 4}); // expected-error {{array has incomplete element type 'struct GH137845_Data'}} \ + expected-warning {{too many braces around scalar initializer}} \ + expected-warning {{excess elements in scalar initializer}} +} + +// GH69213 +int GH69213_ptr; +void GH69213(void) { + *GH69213_ptr = (int){{}, 0}; // expected-error {{indirection requires pointer operand ('int' invalid)}} \ + expected-warning {{too many braces around scalar initializer}} \ + expected-warning {{excess elements in scalar initializer}} +} + +// GH198767 +void GH198767(void) { + static __thread static char buffer[128] = {{{}, 0}}; // expected-warning {{duplicate 'static' declaration specifier}} \ + expected-warning {{too many braces around scalar initializer}} \ + expected-warning {{excess elements in scalar initializer}} +} + +struct GH207566 {}; +struct GH207566 **GH207566_s = {{}, NULL}; // expected-warning {{too many braces around scalar initializer}} \ + expected-warning {{excess elements in scalar initializer}} +GH106180 = {{}, 1}; // expected-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}} \ + expected-warning {{too many braces around scalar initializer}} \ + expected-warning {{excess elements in scalar initializer}} >From 540e6e541489659aa33da41dbeeda303618a3190 Mon Sep 17 00:00:00 2001 From: tobiichi3227 <[email protected]> Date: Thu, 30 Jul 2026 14:17:48 +0800 Subject: [PATCH 5/6] [clang] Add release note entry --- clang/docs/ReleaseNotes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index ac70a35a8b456..8e20e0a0d91fc 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -365,6 +365,7 @@ features cannot lower the translation-unit ABI level; - Fixed a bug where `__func__`, `__PRETTY_FUNCTION__` and `__FUNCTION__` were not resolving to the proper function when inside a lambda return type (#GH211811) - Fixed USR generation for declarations whose signature mentions a class-type non-type template parameter. (#GH212351) +- Fixed a crash when checking scalar type with excess braces. (#GH69213, #GH137845, #GH198767, #GH207566, #GH106180) #### Bug Fixes to Compiler Builtins >From 194f5ed507ba3a12813e63b655124c80b58a388d Mon Sep 17 00:00:00 2001 From: tobiichi3227 <[email protected]> Date: Fri, 7 Aug 2026 16:53:08 +0800 Subject: [PATCH 6/6] [clang][Sema] Apply clang-format to initializer fix --- clang/lib/Sema/SemaInit.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 5a097dcb2c3b1..fd00b1d02fa18 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -1362,8 +1362,8 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity, // Don't complain for incomplete types, since we'll get an error elsewhere. if ((Index < IList->getNumInits() || CurEmbed) && !T->isIncompleteType()) { // We have leftover initializers - Expr *ExtraInit = Index < IList->getNumInits() ? IList->getInit(Index) - : CurEmbed; + Expr *ExtraInit = + Index < IList->getNumInits() ? IList->getInit(Index) : CurEmbed; SourceLocation ExtraInitLoc = ExtraInit ? ExtraInit->getBeginLoc() : IList->getEndLoc(); SourceRange ExtraInitRange = @@ -1373,8 +1373,7 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity, hadError = ExtraInitsIsError; if (VerifyOnly) { return; - } else if (StructuredIndex == 1 && - StructuredList->getNumInits() != 0 && + } else if (StructuredIndex == 1 && StructuredList->getNumInits() != 0 && StructuredList->getInit(0) && IsStringInit(StructuredList->getInit(0), T, SemaRef.Context) == SIF_None) { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
