https://github.com/oToToT updated 
https://github.com/llvm/llvm-project/pull/184865

>From 9197cab1ff0ba98af5f660e7894a0943e10d43f1 Mon Sep 17 00:00:00 2001
From: Tommy Chiang <[email protected]>
Date: Fri, 6 Mar 2026 03:09:40 +0800
Subject: [PATCH] [Clang][ExprConst] Gracefully reject APValue::LValue in
 BitCast

Instead of marking the branch unreachable, emit an unsupported type
diagnostic and return false when encountering `APValue::LValue` in
`APValueToBufferConverter`.

A good example of this is:
```
long fn() {
  return __builtin_bit_cast(long, (long)&fn);
}
```

Although `&fn` itself is a pointer type, the cast `(long)` converts it
to an integer type, which passes `checkBitCastConstexprEligibilityType`.
Thus, eventually, we see it in Converter, which does not expect an
LValue.

Fixes https://github.com/llvm/llvm-project/issues/44991
---
 clang/lib/AST/ExprConstant.cpp            | 4 +---
 clang/test/CodeGen/bitcast-based-lvalue.c | 7 +++++++
 2 files changed, 8 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/CodeGen/bitcast-based-lvalue.c

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f233ff76632ae..515dea59c3b82 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -7771,6 +7771,7 @@ class APValueToBufferConverter {
     case APValue::FixedPoint:
       // FIXME: We should support these.
 
+    case APValue::LValue:
     case APValue::Matrix:
     case APValue::Union:
     case APValue::MemberPointer:
@@ -7780,9 +7781,6 @@ class APValueToBufferConverter {
           << Ty;
       return false;
     }
-
-    case APValue::LValue:
-      llvm_unreachable("LValue subobject in bit_cast?");
     }
     llvm_unreachable("Unhandled APValue::ValueKind");
   }
diff --git a/clang/test/CodeGen/bitcast-based-lvalue.c 
b/clang/test/CodeGen/bitcast-based-lvalue.c
new file mode 100644
index 0000000000000..af64c6fe97ce9
--- /dev/null
+++ b/clang/test/CodeGen/bitcast-based-lvalue.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | 
FileCheck %s
+
+long fn(void) { return __builtin_bit_cast(long, (long)&fn); }
+
+// CHECK-LABEL: define{{.*}} i64 @fn()
+// CHECK: store i64 ptrtoint (ptr @fn to i64), ptr %ref.tmp, align 8
+// CHECK: ret i64 %{{.*}}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to