[clang] [clang][bytecode] Fix null ptr upcasts adding offset (PR #224873)
Benji Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 22 05:18:53 PDT 2026
https://github.com/Benjins updated https://github.com/llvm/llvm-project/pull/224873
>From 940c0518978692b0a339bc909264b0e93f411f62 Mon Sep 17 00:00:00 2001
From: Benji Smith <benjsith at gmail.com>
Date: Sat, 19 Sep 2026 19:17:18 -0400
Subject: [PATCH 1/3] [clang][bytecode] Fix null ptr upcasts adding offset
Previously, this was applying the offset it would for non-null pointers, but
null pointers should always cast to a null pointer result.
Fixes https://github.com/llvm/llvm-project/issues/224869
---
clang/docs/ReleaseNotes.md | 3 +++
clang/lib/AST/ByteCode/Pointer.cpp | 4 ++++
clang/test/AST/ByteCode/const-base-cast.cpp | 5 +++++
3 files changed, 12 insertions(+)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index a1f24a8caedae..684b02fb0af1a 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -727,6 +727,9 @@ features cannot lower the translation-unit ABI level;
- Fixed ambiguous overload where two non-static member functions with
different signatures could be incorrectly considered equivalent. (#GH224499)
+- Fixed the bytecode interpreter evaluating upcasted null pointers to a
+ non-null pointer. (#GH224869)
+
#### Bug Fixes to AST Handling
- Fixed a non-deterministic ordering of unused local typedefs that made
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index dca2630138a4e..fb05efe5a62c3 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -1373,6 +1373,10 @@ IntPointer IntPointer::baseCast(const interp::Context &Ctx,
if (CurType.isNull() || !CurType->isRecordType())
return *this;
+ // null pointers stay null during a cast, per conv.ptr
+ if (Value == 0)
+ return *this;
+
const Record *R = Ctx.getRecord(CurType->getAsRecordDecl());
// This iterates over bases and checks for the proper offset. That's
diff --git a/clang/test/AST/ByteCode/const-base-cast.cpp b/clang/test/AST/ByteCode/const-base-cast.cpp
index 80226b973bf97..696eff5959cc4 100644
--- a/clang/test/AST/ByteCode/const-base-cast.cpp
+++ b/clang/test/AST/ByteCode/const-base-cast.cpp
@@ -17,3 +17,8 @@ unsigned char y = ((char*)(B*)(C*)0x1000) - (char*)0x1000;
unsigned char z = ((char*)(A*)(C*)0x1000) - (char*)0x1000;
// CHECK: @z = {{(dso_local )?}}global i8 0
+unsigned char n0 = ((char*)(B*)(C*)0) - (char*)0;
+// CHECK: @n0 = {{(dso_local )?}}global i8 0
+
+unsigned char n1 = ((char*)(A*)(C*)0) - (char*)0;
+// CHECK: @n1 = {{(dso_local )?}}global i8 0
>From 860d9a6079078e53603693009040c48b89570b8d Mon Sep 17 00:00:00 2001
From: Benji Smith <benjsith at gmail.com>
Date: Mon, 21 Sep 2026 11:57:41 -0400
Subject: [PATCH 2/3] Remove release notes reference for clang bytecode change
---
clang/docs/ReleaseNotes.md | 3 ---
1 file changed, 3 deletions(-)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 684b02fb0af1a..a1f24a8caedae 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -727,9 +727,6 @@ features cannot lower the translation-unit ABI level;
- Fixed ambiguous overload where two non-static member functions with
different signatures could be incorrectly considered equivalent. (#GH224499)
-- Fixed the bytecode interpreter evaluating upcasted null pointers to a
- non-null pointer. (#GH224869)
-
#### Bug Fixes to AST Handling
- Fixed a non-deterministic ordering of unused local typedefs that made
>From 61b9e69cbd288264bda7bea1e97fb529c4e6030f Mon Sep 17 00:00:00 2001
From: Benji Smith <benjsith at gmail.com>
Date: Tue, 22 Sep 2026 08:18:25 -0400
Subject: [PATCH 3/3] Add additional test case for unrelated struct ptr cast of
null
---
clang/test/AST/ByteCode/const-base-cast.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/clang/test/AST/ByteCode/const-base-cast.cpp b/clang/test/AST/ByteCode/const-base-cast.cpp
index 696eff5959cc4..6f016e0aed11c 100644
--- a/clang/test/AST/ByteCode/const-base-cast.cpp
+++ b/clang/test/AST/ByteCode/const-base-cast.cpp
@@ -22,3 +22,7 @@ unsigned char n0 = ((char*)(B*)(C*)0) - (char*)0;
unsigned char n1 = ((char*)(A*)(C*)0) - (char*)0;
// CHECK: @n1 = {{(dso_local )?}}global i8 0
+
+struct F {};
+unsigned char n2 = ((char*)(F*)(C*)0) - (char*)0;
+// CHECK: @n2 = {{(dso_local )?}}global i8 0
More information about the cfe-commits
mailing list