[clang] [clang][Sema] Fix crash when checking scalar type with excess braces (PR #192471)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 12 02:58:45 PDT 2026
https://github.com/tobiichi3227 updated https://github.com/llvm/llvm-project/pull/192471
>From 5de8fc55699c124400ff3bf29fd5620b87fe9ef4 Mon Sep 17 00:00:00 2001
From: tobiichi3227 <cz1346219 at gmail.com>
Date: Thu, 16 Apr 2026 22:43:04 +0800
Subject: [PATCH 1/7] [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 c9c3c5eec00736c3b79006d75dbe486652f7c9e6 Mon Sep 17 00:00:00 2001
From: tobiichi3227 <cz1346219 at gmail.com>
Date: Fri, 1 May 2026 02:36:33 +0800
Subject: [PATCH 2/7] 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 5250de7f9b6b8a1b11ece47d95c0c7ce3e405057 Mon Sep 17 00:00:00 2001
From: tobiichi3227 <cz1346219 at gmail.com>
Date: Sat, 2 May 2026 10:35:35 +0800
Subject: [PATCH 3/7] 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 0ced308a86dce6b329636929a353ccf227653a3f Mon Sep 17 00:00:00 2001
From: tobiichi3227 <cz1346219 at gmail.com>
Date: Thu, 30 Jul 2026 14:03:54 +0800
Subject: [PATCH 4/7] Add more regression tests from gh issue
Fix #137845, #69213, #198767, #207566, #106180
---
clang/docs/ReleaseNotes.md | 1 +
clang/test/Sema/init.c | 46 +++++++++++++++++++++++++++++++++-----
2 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index b5aa71119e4b7..89b92dbf28e76 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -397,6 +397,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)
- Fixed an assertion crash when instantiating a nested requirement with an invalid constraint. (#GH213575)
- Clang now defines the GCC-compatible predefined macro `__SIG_ATOMIC_TYPE__`. (#GH213895)
- Fixed a bug where a stray closing curley brace in an OpenMP/OpenACC pragma could cause pragma parsing issues when inside of a member function. (#GH214195)
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 366e6d96da814e6037455b31a6290c67f0542ec3 Mon Sep 17 00:00:00 2001
From: tobiichi3227 <cz1346219 at gmail.com>
Date: Fri, 7 Aug 2026 16:53:08 +0800
Subject: [PATCH 5/7] [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) {
>From ffe8941c3746f31c60c97d1e16d155dd10a708e0 Mon Sep 17 00:00:00 2001
From: tobiichi3227 <cz1346219 at gmail.com>
Date: Sat, 8 Aug 2026 13:30:56 +0800
Subject: [PATCH 6/7] [clang][Sema] Test excess braces with #embed
---
clang/test/Sema/init.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/clang/test/Sema/init.c b/clang/test/Sema/init.c
index 0f333ee309d9d..32a0a94a8b8a6 100644
--- a/clang/test/Sema/init.c
+++ b/clang/test/Sema/init.c
@@ -216,6 +216,13 @@ char PR192471_3[1] = {
, 49, 49, 49, 48 // expected-warning {{excess elements in array initializer}}
};
+void PR192471_4(int *ptr) {
+ *ptr = (int){{}, // expected-warning {{too many braces around scalar initializer}}
+#embed __FILE__ limit(1) // expected-warning {{#embed is a C23 extension}} \
+ expected-warning {{excess elements in scalar initializer}}
+ };
+}
+
// GH137845
struct GH137845_Data; // expected-note 2 {{forward declaration of 'struct GH137845_Data'}}
double GH137845_swap(struct GH137845_Data *, struct GH137845_Data *);
>From f4d5ea967df22f25f1024a32b0024bcc41f18c1c Mon Sep 17 00:00:00 2001
From: tobiichi3227 <cz1346219 at gmail.com>
Date: Wed, 12 Aug 2026 17:57:55 +0800
Subject: [PATCH 7/7] [clang] Fix syntax error in release note
---
clang/docs/ReleaseNotes.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 89b92dbf28e76..9648ad429d040 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -397,7 +397,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)
+- Fixed a crash when checking scalar type with excess braces. (#GH69213), (#GH137845), (#GH198767), (#GH207566), (#GH106180)
- Fixed an assertion crash when instantiating a nested requirement with an invalid constraint. (#GH213575)
- Clang now defines the GCC-compatible predefined macro `__SIG_ATOMIC_TYPE__`. (#GH213895)
- Fixed a bug where a stray closing curley brace in an OpenMP/OpenACC pragma could cause pragma parsing issues when inside of a member function. (#GH214195)
More information about the cfe-commits
mailing list