Skip to content

Conversation

@tbaederr
Copy link
Contributor

@tbaederr tbaederr commented Nov 5, 2024

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

Optionally prepare storage for the result and do the bitcast anyway,
to get the right diagnostic output.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Nov 5, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 5, 2024

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/114926.diff

2 Files Affected:

  • (modified) clang/lib/AST/ByteCode/Compiler.cpp (+14-4)
  • (modified) clang/test/AST/ByteCode/builtin-bit-cast.cpp (+7)
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

@tbaederr tbaederr merged commit 5f84b33 into llvm:main Nov 5, 2024
11 checks passed
PhilippRados pushed a commit to PhilippRados/llvm-project that referenced this pull request Nov 6, 2024
Optionally prepare storage for the result and do the bitcast anyway, to
get the right diagnostic output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants