[clang] [clang][bytecode] Fix discarding __builtin_bit_cast calls (PR #114926)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 4 20:54:19 PST 2024


https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/114926

Optionally prepare storage for the result and do the bitcast anyway, to get the right diagnostic output.

>From 76e549b6fab3021050148ee0555b7ac6ea20b7ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 5 Nov 2024 05:51:14 +0100
Subject: [PATCH] [clang][bytecode] Fix discarding __builtin_bit_cast calls

Optionally prepare storage for the result and do the bitcast anyway,
to get the right diagnostic output.
---
 clang/lib/AST/ByteCode/Compiler.cpp          | 18 ++++++++++++++----
 clang/test/AST/ByteCode/builtin-bit-cast.cpp |  7 +++++++
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 35116952901684..80f3160fd75563 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -6446,8 +6446,6 @@ bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) {
   QualType ToType = E->getType();
   std::optional<PrimType> ToT = classify(ToType);
 
-  assert(!DiscardResult && "Implement DiscardResult mode for bitcasts.");
-
   if (ToType->isNullPtrType()) {
     if (!this->discard(SubExpr))
       return false;
@@ -6463,12 +6461,24 @@ bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) {
   }
   assert(!ToType->isReferenceType());
 
+  // Prepare storage for the result in case we discard.
+  if (DiscardResult && !Initializing && !ToT) {
+    std::optional<unsigned> LocalIndex = allocateLocal(E);
+    if (!LocalIndex)
+      return false;
+    if (!this->emitGetPtrLocal(*LocalIndex, E))
+      return false;
+  }
+
   // Get a pointer to the value-to-cast on the stack.
   if (!this->visit(SubExpr))
     return false;
 
-  if (!ToT || ToT == PT_Ptr)
-    return this->emitBitCastPtr(E);
+  if (!ToT || ToT == PT_Ptr) {
+    if (!this->emitBitCastPtr(E))
+      return false;
+    return DiscardResult ? this->emitPopPtr(E) : true;
+  }
   assert(ToT);
 
   const llvm::fltSemantics *TargetSemantics = nullptr;
diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
index 50382399eefc9c..c381911bc39837 100644
--- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp
+++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
@@ -38,6 +38,13 @@ constexpr Init round_trip(const Init &init) {
   return bit_cast<Init>(bit_cast<Intermediate>(init));
 }
 
+
+namespace Discarding {
+  struct S { int a; };
+  constexpr int f = (__builtin_bit_cast(int, 2), 0);
+  constexpr int f2 = (__builtin_bit_cast(S, 2), 0);
+}
+
 namespace std {
 enum byte : unsigned char {};
 } // namespace std



More information about the cfe-commits mailing list