[clang] [clang][bytecode] Fix crash on arrays with excessive size (PR #175402)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 11 11:03:31 PST 2026
https://github.com/nataliakokoromyti updated https://github.com/llvm/llvm-project/pull/175402
>From 937c71377b4a6858c107ef351cd3bb968939dc4b Mon Sep 17 00:00:00 2001
From: Natalia Kokoromyti <nataliakokoromyti at gmail.com>
Date: Sat, 10 Jan 2026 16:29:17 -0800
Subject: [PATCH 1/4] [clang][bytecode] Fix crash on arrays with excessive size
The bytecode interpreter was crashing when encountering arrays with
sizes that exceed Descriptor::MaxArrayElemBytes. The bounds check in
Program::createDescriptor was using std::numeric_limits<unsigned>::max()
instead of the correct limit Descriptor::MaxArrayElemBytes.
This caused the check to pass for sizes that would later fail the
assertion in the Descriptor constructor.
Fixes #175293
---
clang/lib/AST/ByteCode/Program.cpp | 4 ++--
clang/test/AST/ByteCode/huge-array-size.cpp | 10 ++++++++++
2 files changed, 12 insertions(+), 2 deletions(-)
create mode 100644 clang/test/AST/ByteCode/huge-array-size.cpp
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index d96934071cb60..a9ed47df89a86 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -411,7 +411,7 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
if (OptPrimType T = Ctx.classify(ElemTy)) {
// Arrays of primitives.
unsigned ElemSize = primSize(*T);
- if (std::numeric_limits<unsigned>::max() / ElemSize <= NumElems) {
+ if (Descriptor::MaxArrayElemBytes / ElemSize < NumElems) {
return {};
}
return allocateDescriptor(D, *T, MDSize, NumElems, IsConst, IsTemporary,
@@ -424,7 +424,7 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
if (!ElemDesc)
return nullptr;
unsigned ElemSize = ElemDesc->getAllocSize() + sizeof(InlineDescriptor);
- if (std::numeric_limits<unsigned>::max() / ElemSize <= NumElems)
+ if (Descriptor::MaxArrayElemBytes / ElemSize < NumElems)
return {};
return allocateDescriptor(D, Ty, ElemDesc, MDSize, NumElems, IsConst,
IsTemporary, IsMutable);
diff --git a/clang/test/AST/ByteCode/huge-array-size.cpp b/clang/test/AST/ByteCode/huge-array-size.cpp
new file mode 100644
index 0000000000000..2425aedcdad4a
--- /dev/null
+++ b/clang/test/AST/ByteCode/huge-array-size.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -fsyntax-only %s
+// RUN: %clang_cc1 -fsyntax-only %s
+
+// This test checks that we don't crash when encountering arrays with
+// sizes that exceed the bytecode interpreter's limits.
+// See: https://github.com/llvm/llvm-project/issues/175293
+
+char q[-2U];
+
+void foo() { char *p = q + 1; }
>From 738d200b563b6ddb322e2f24703c881e06c0909f Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <126305457+nataliakokoromyti at users.noreply.github.com>
Date: Sun, 11 Jan 2026 03:34:14 -0800
Subject: [PATCH 2/4] add parentheses
---
clang/lib/AST/ByteCode/Program.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index a9ed47df89a86..edc6e11a842df 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -411,7 +411,7 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
if (OptPrimType T = Ctx.classify(ElemTy)) {
// Arrays of primitives.
unsigned ElemSize = primSize(*T);
- if (Descriptor::MaxArrayElemBytes / ElemSize < NumElems) {
+ if ((Descriptor::MaxArrayElemBytes / ElemSize) < NumElems) {
return {};
}
return allocateDescriptor(D, *T, MDSize, NumElems, IsConst, IsTemporary,
>From 5b39f501df99fe0552e9faec349f4cd89b81c9df Mon Sep 17 00:00:00 2001
From: Natalia Kokoromyti <nataliakokoromyti at gmail.com>
Date: Sun, 11 Jan 2026 04:10:42 -0800
Subject: [PATCH 3/4] move test to codegen.cpp + check q size
---
clang/test/AST/ByteCode/codegen.cpp | 15 ++++++---------
clang/test/AST/ByteCode/huge-array-size.cpp | 10 ----------
2 files changed, 6 insertions(+), 19 deletions(-)
delete mode 100644 clang/test/AST/ByteCode/huge-array-size.cpp
diff --git a/clang/test/AST/ByteCode/codegen.cpp b/clang/test/AST/ByteCode/codegen.cpp
index 1bc756c515ac8..f7134c062162c 100644
--- a/clang/test/AST/ByteCode/codegen.cpp
+++ b/clang/test/AST/ByteCode/codegen.cpp
@@ -13,6 +13,12 @@ int &pastEnd = arr[2];
// CHECK: @F = constant ptr @arr, align 8
int &F = arr[0];
+/// Ensure we don't crash on arrays with huge (overflowed) sizes.
+/// https://github.com/llvm/llvm-project/issues/175293
+// CHECK: @_ZL1q = internal global [4294967294 x i8] zeroinitializer, align 16
+static char q[-2U];
+void useQ() { char *p = q + 1; }
+
struct S {
int a;
float c[3];
@@ -130,12 +136,3 @@ class X {
extern X OuterX;
-X test24() {
- X x;
- if (&x == &OuterX)
- throw 0;
- return x;
-}
-// CHECK: _Z6test24v
-// CHECK-NOT: eh.resume
-// CHECK-NOT: unreachable
diff --git a/clang/test/AST/ByteCode/huge-array-size.cpp b/clang/test/AST/ByteCode/huge-array-size.cpp
deleted file mode 100644
index 2425aedcdad4a..0000000000000
--- a/clang/test/AST/ByteCode/huge-array-size.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -fsyntax-only %s
-// RUN: %clang_cc1 -fsyntax-only %s
-
-// This test checks that we don't crash when encountering arrays with
-// sizes that exceed the bytecode interpreter's limits.
-// See: https://github.com/llvm/llvm-project/issues/175293
-
-char q[-2U];
-
-void foo() { char *p = q + 1; }
>From 7177ae98082949b840c9cb67e10c9faf23ac6676 Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <126305457+nataliakokoromyti at users.noreply.github.com>
Date: Sun, 11 Jan 2026 11:03:21 -0800
Subject: [PATCH 4/4] only apply MaxArrayElemBytes to primitive arrays
---
clang/lib/AST/ByteCode/Program.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index edc6e11a842df..d038c30d1ef82 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -424,7 +424,7 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
if (!ElemDesc)
return nullptr;
unsigned ElemSize = ElemDesc->getAllocSize() + sizeof(InlineDescriptor);
- if (Descriptor::MaxArrayElemBytes / ElemSize < NumElems)
+ if (std::numeric_limits<unsigned>::max() / ElemSize <= NumElems)
return {};
return allocateDescriptor(D, Ty, ElemDesc, MDSize, NumElems, IsConst,
IsTemporary, IsMutable);
More information about the cfe-commits
mailing list