[clang] [clang][bytecode] Fix bitcasting from null pointers (PR #116999)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 5 03:02:49 PST 2024


https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/116999

>From c9c39e81e3fae1351691feaf99528997114810cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Wed, 20 Nov 2024 17:14:01 +0100
Subject: [PATCH] [clang][bytecode] Fix bitcasting from null pointers

This looks a little ugly now, I should wait for #116843.
---
 clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp | 10 +++++++---
 clang/test/AST/ByteCode/builtin-bit-cast.cpp    |  6 ++++++
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
index 03c556cd70bb7a..6ee3826fb3eea6 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
@@ -254,9 +254,13 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
         }
 
         assert(P.isInitialized());
-        // nullptr_t is a PT_Ptr for us, but it's still not std::is_pointer_v.
-        if (T == PT_Ptr)
-          assert(false && "Implement casting to pointer types");
+        if (T == PT_Ptr) {
+          assert(P.getType()->isNullPtrType());
+          // Clang treats nullptr_t has having NO bits in its value
+          // representation. So, we accept it here and leave its bits
+          // uninitialized.
+          return true;
+        }
 
         auto Buff =
             std::make_unique<std::byte[]>(ObjectReprChars.getQuantity());
diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
index d3935b4f921b3f..f89eb3584bbcff 100644
--- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp
+++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
@@ -133,8 +133,14 @@ namespace simple {
 
   /// This works in GCC and in the bytecode interpreter, but the current interpreter
   /// diagnoses it.
+  /// FIXME: Should also be rejected in the bytecode interpreter.
   static_assert(__builtin_bit_cast(intptr_t, nullptr) == 0); // ref-error {{not an integral constant expression}} \
                                                              // ref-note {{indeterminate value can only initialize an object}}
+
+  constexpr int test_from_nullptr_pass = (__builtin_bit_cast(unsigned char[sizeof(nullptr)], nullptr), 0);
+  constexpr unsigned char NPData[sizeof(nullptr)] = {1,2,3,4};
+  constexpr nullptr_t NP = __builtin_bit_cast(nullptr_t, NPData);
+  static_assert(NP == nullptr);
 }
 
 namespace Fail {



More information about the cfe-commits mailing list