[clang] [clang][NFC] Add tests for static_cast<T&&> of a bit-field lvalue. (PR #231092)
Aditya Chaudhary via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 12 02:20:56 PDT 2026
https://github.com/aditya-chaudhary1 updated https://github.com/llvm/llvm-project/pull/231092
>From 495e9651b0a44f482651e946ea1c1f5d4e784e61 Mon Sep 17 00:00:00 2001
From: Aditya Chaudhary <Aditya.Chaudhary1 at ibm.com>
Date: Mon, 12 Oct 2026 12:25:04 +0530
Subject: [PATCH] Precommit tests that record clang current handling
---
.../test/AST/ast-dump-rvalue-ref-bitfield.cpp | 29 +++++++++++++++++++
clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp | 28 ++++++++++++++++++
2 files changed, 57 insertions(+)
create mode 100644 clang/test/AST/ast-dump-rvalue-ref-bitfield.cpp
create mode 100644 clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp
diff --git a/clang/test/AST/ast-dump-rvalue-ref-bitfield.cpp b/clang/test/AST/ast-dump-rvalue-ref-bitfield.cpp
new file mode 100644
index 00000000000000..38ed402ef38982
--- /dev/null
+++ b/clang/test/AST/ast-dump-rvalue-ref-bitfield.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++11 -fsyntax-only \
+// RUN: -ast-dump -ast-dump-filter test %s | FileCheck %s
+
+// static_cast<T&&> applied to a bit-field lvalue. A bit-field has no address,
+// so the reference has to bind to a materialized temporary.
+//
+// FIXME: Clang currently binds the reference directly to the bit-field. No
+// MaterializeTemporaryExpr or LValueToRValue conversion is created, and this
+// AST crashes CodeGen (see CodeGenCXX/rvalue-ref-bitfield.cpp).
+
+struct A {
+ int a : 4;
+ int b : 1;
+};
+
+void test(A obj) {
+ int &&r = static_cast<int &&>(obj.a);
+ const int &&cr = static_cast<const int &&>(obj.a);
+}
+
+// CHECK-LABEL: FunctionDecl {{.*}} test 'void (A)'
+// CHECK: VarDecl {{.*}} r 'int &&' cinit
+// CHECK-NEXT: `-CXXStaticCastExpr {{.*}} 'int' xvalue static_cast<int &&> <NoOp>
+// CHECK-NEXT: `-MemberExpr {{.*}} 'int' lvalue bitfield .a
+// CHECK-NEXT: `-DeclRefExpr {{.*}} 'A' lvalue ParmVar {{.*}} 'obj' 'A'
+// CHECK: VarDecl {{.*}} cr 'const int &&' cinit
+// CHECK-NEXT: `-CXXStaticCastExpr {{.*}} 'const int' xvalue static_cast<const int &&> <NoOp>
+// CHECK-NEXT: `-MemberExpr {{.*}} 'int' lvalue bitfield .a
+// CHECK-NEXT: `-DeclRefExpr {{.*}} 'A' lvalue ParmVar {{.*}} 'obj' 'A'
diff --git a/clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp b/clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp
new file mode 100644
index 00000000000000..8966178f3a9bad
--- /dev/null
+++ b/clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp
@@ -0,0 +1,28 @@
+// REQUIRES: asserts
+// RUN: not --crash %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown \
+// RUN: -emit-llvm -o - %s -DNONCONST 2>&1 | FileCheck %s --check-prefix=CHECK-NONCONST
+// RUN: not --crash %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown \
+// RUN: -emit-llvm -o - %s -DCONST 2>&1 | FileCheck %s --check-prefix=CHECK-CONST
+
+// static_cast<T&&> of a bit-field lvalue should materialize a temporary.
+// FIXME: Sema binds the reference directly to the bit-field, so CodeGen
+// receives a bit-field LValue and asserts in EmitReferenceBindingToExpr.
+// Each case is guarded by its own macro because the crash aborts the whole
+// compilation.
+
+struct A {
+ int a : 4;
+};
+
+// CHECK-LABEL: define {{.*}} @_Z4test1A(
+void test(A obj) {
+ #ifdef NONCONST
+ // CHECK-NONCONST: {{Assertion.*LV.isSimple\(\)}}
+ int &&ri = static_cast<int&&>(obj.a);
+ #endif
+
+#ifdef CONST
+ // CHECK-CONST: {{Assertion.*LV.isSimple\(\)}}
+ const int &&cri = static_cast<const int &&>(obj.a);
+ #endif
+}
More information about the cfe-commits
mailing list