https://github.com/aditya-chaudhary1 updated 
https://github.com/llvm/llvm-project/pull/231256

>From e87c10ed80320e315e4862e16368a6d2daf46de4 Mon Sep 17 00:00:00 2001
From: Aditya Chaudhary <[email protected]>
Date: Fri, 9 Oct 2026 14:51:28 +0530
Subject: [PATCH 1/3] handle rvalue ref of a bit-field in TryStaticImplicitCast

---
 clang/lib/Sema/SemaCast.cpp                   |  6 ++++
 clang/lib/Sema/SemaInit.cpp                   |  5 +++-
 clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp | 28 +++++++++++++++++++
 3 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp

diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index c797bdb11e0cb..e97dbd8ecd0f7 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -1633,6 +1633,12 @@ TryCastResult TryLValueToRValueCast(Sema &Self, Expr 
*SrcExpr,
   if (!SrcExpr->isGLValue())
     return TC_NotApplicable;
 
+  // A bit-field lvalue cannot be directly bound to an rvalue reference; it
+  // has no address.  Fall through to TryStaticImplicitCast so the initializer
+  // sequence materializes a temporary and binds to that instead.
+  if (SrcExpr->refersToBitField())
+    return TC_NotApplicable;
+
   // Because we try the reference downcast before this function, from now on
   // this is the only cast possibility, so we issue an error if we fail now.
   QualType FromType = SrcExpr->getType();
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 3f30e94aa8976..6b02c943c343f 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -5800,8 +5800,11 @@ static void TryReferenceInitializationCore(Sema &S,
 
   //   [...] If T1 is reference-related to T2 and the reference is an rvalue
   //   reference, the initializer expression shall not be an lvalue.
+  //   However, a non-referenceable glvalue (bit-field, vector element, matrix
+  //   element) cannot be bound directly, so it is materialized into a
+  //   temporary regardless of value category — don't block it here.
   if (RefRelationship >= Sema::Ref_Related && !isLValueRef &&
-      InitCategory.isLValue()) {
+      InitCategory.isLValue() && !isNonReferenceableGLValue(Initializer)) {
     Sequence.SetFailed(
                     InitializationSequence::FK_RValueReferenceBindingToLValue);
     return;
diff --git a/clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp 
b/clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp
new file mode 100644
index 0000000000000..6a248132bc302
--- /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
+}

>From 46391d301e178c4fec8ea2dc4800b5c923ab8801 Mon Sep 17 00:00:00 2001
From: Aditya Chaudhary <[email protected]>
Date: Mon, 12 Oct 2026 18:45:54 +0530
Subject: [PATCH 2/3] updated the test file and added test to check AST dump

---
 .../test/AST/ast-dump-rvalue-ref-bitfield.cpp | 32 +++++++++++++++
 clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp | 39 +++++++++++--------
 2 files changed, 55 insertions(+), 16 deletions(-)
 create mode 100644 clang/test/AST/ast-dump-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 0000000000000..7d8ecec393d0a
--- /dev/null
+++ b/clang/test/AST/ast-dump-rvalue-ref-bitfield.cpp
@@ -0,0 +1,32 @@
+// 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 binds to a materialized temporary initialized from an
+// LValueToRValue conversion of the bit-field.
+
+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:  `-ExprWithCleanups {{.*}} 'int' xvalue
+// CHECK-NEXT:    `-CXXStaticCastExpr {{.*}} 'int' xvalue static_cast<int &&> 
<NoOp>
+// CHECK-NEXT:      `-MaterializeTemporaryExpr {{.*}} 'int' xvalue extended by 
Var {{.*}} 'r' 'int &&'
+// CHECK-NEXT:        `-ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// CHECK-NEXT:          `-MemberExpr {{.*}} 'int' lvalue bitfield .a
+// CHECK-NEXT:            `-DeclRefExpr {{.*}} 'A' lvalue ParmVar {{.*}} 'obj' 
'A'
+// CHECK:       VarDecl {{.*}} cr 'const int &&' cinit
+// CHECK-NEXT:  `-ExprWithCleanups {{.*}} 'const int' xvalue
+// CHECK-NEXT:    `-CXXStaticCastExpr {{.*}} 'const int' xvalue 
static_cast<const int &&> <NoOp>
+// CHECK-NEXT:      `-MaterializeTemporaryExpr {{.*}} 'const int' xvalue 
extended by Var {{.*}} 'cr' 'const int &&'
+// CHECK-NEXT:        `-ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// 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
index 6a248132bc302..7144d9c845a9d 100644
--- a/clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp
+++ b/clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp
@@ -1,14 +1,8 @@
-// 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
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown \
+// RUN:   -emit-llvm -o - %s | FileCheck %s
 
-// 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.
+// static_cast<T&&> of a bit-field lvalue materializes a temporary holding the
+// loaded bit-field value, and the reference binds to that temporary.
 
 struct A {
   int a : 4;
@@ -16,13 +10,26 @@ struct A {
 
 // CHECK-LABEL: define {{.*}} @_Z4test1A(
 void test(A obj) {
-  #ifdef NONCONST
-  // CHECK-NONCONST: {{Assertion.*LV.isSimple\(\)}}
+  // CHECK:      %[[OBJ:.*]] = alloca %struct.A
+  // CHECK-NEXT: %[[RI:.*]] = alloca ptr
+  // CHECK-NEXT: %[[TMP1:.*]] = alloca i32
+  // CHECK-NEXT: %[[CRI:.*]] = alloca ptr
+  // CHECK-NEXT: %[[TMP2:.*]] = alloca i32
+  // CHECK-NEXT: store i32 %obj.coerce, ptr %[[OBJ]]
+
+  // CHECK-NEXT: %[[LD1:.*]] = load i8, ptr %[[OBJ]]
+  // CHECK-NEXT: %[[SHL1:.*]] = shl i8 %[[LD1]], 4
+  // CHECK-NEXT: %[[ASHR1:.*]] = ashr i8 %[[SHL1]], 4
+  // CHECK-NEXT: %[[CAST1:.*]] = sext i8 %[[ASHR1]] to i32
+  // CHECK-NEXT: store i32 %[[CAST1]], ptr %[[TMP1]]
+  // CHECK-NEXT: store ptr %[[TMP1]], ptr %[[RI]]
   int &&ri = static_cast<int&&>(obj.a);
-  #endif
 
-  #ifdef CONST
-  // CHECK-CONST: {{Assertion.*LV.isSimple\(\)}}
+  // CHECK-NEXT: %[[LD2:.*]] = load i8, ptr %[[OBJ]]
+  // CHECK-NEXT: %[[SHL2:.*]] = shl i8 %[[LD2]], 4
+  // CHECK-NEXT: %[[ASHR2:.*]] = ashr i8 %[[SHL2]], 4
+  // CHECK-NEXT: %[[CAST2:.*]] = sext i8 %[[ASHR2]] to i32
+  // CHECK-NEXT: store i32 %[[CAST2]], ptr %[[TMP2]]
+  // CHECK-NEXT: store ptr %[[TMP2]], ptr %[[CRI]]
   const int &&cri = static_cast<const int &&>(obj.a);
-  #endif
 }

>From 19c12610211f15536ed8b20c70b3ae5d19e323ca Mon Sep 17 00:00:00 2001
From: Aditya Chaudhary <[email protected]>
Date: Mon, 19 Oct 2026 14:53:19 +0530
Subject: [PATCH 3/3] added test file

---
 clang/lib/Sema/SemaCast.cpp                   | 34 ++++++++++-------
 clang/lib/Sema/SemaInit.cpp                   |  5 +--
 .../test/AST/ast-dump-rvalue-ref-bitfield.cpp | 21 +++++-----
 .../dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp  |  1 +
 clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp |  4 +-
 .../static-cast-bitfield-temporary.cpp        | 38 +++++++++++++++++++
 6 files changed, 72 insertions(+), 31 deletions(-)
 create mode 100644 clang/test/SemaCXX/static-cast-bitfield-temporary.cpp

diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index e97dbd8ecd0f7..924acc65e76bf 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -262,11 +262,10 @@ static void DiagnoseCastQual(Sema &Self, const ExprResult 
&SrcExpr,
 // %0: Cast Type (a value from the CastType enumeration)
 // %1: Source Type
 // %2: Destination Type
-static TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr,
-                                           QualType DestType, bool CStyle,
-                                           SourceRange OpRange, CastKind &Kind,
-                                           CXXCastPath &BasePath,
-                                           unsigned &msg);
+static TryCastResult
+TryLValueToRValueCast(Sema &Self, ExprResult &SrcExprResult, QualType DestType,
+                      bool CStyle, SourceRange OpRange, CastKind &Kind,
+                      CXXCastPath &BasePath, unsigned &msg);
 static TryCastResult
 TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType,
                            bool CStyle, CastOperation::OpRangeType OpRange,
@@ -1431,8 +1430,10 @@ static TryCastResult TryStaticCast(Sema &Self, 
ExprResult &SrcExpr,
   // C++11 [expr.static.cast]p3:
   //   A glvalue of type "cv1 T1" can be cast to type "rvalue reference to cv2
   //   T2" if "cv2 T2" is reference-compatible with "cv1 T1".
-  tcr = TryLValueToRValueCast(Self, SrcExpr.get(), DestType, CStyle, OpRange,
-                              Kind, BasePath, msg);
+  tcr = TryLValueToRValueCast(Self, SrcExpr, DestType, CStyle, OpRange, Kind,
+                              BasePath, msg);
+  if (SrcExpr.isInvalid())
+    return TC_Failed;
   if (tcr != TC_NotApplicable)
     return tcr;
 
@@ -1619,10 +1620,11 @@ static TryCastResult TryStaticCast(Sema &Self, 
ExprResult &SrcExpr,
 }
 
 /// Tests whether a conversion according to N2844 is valid.
-TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr,
+TryCastResult TryLValueToRValueCast(Sema &Self, ExprResult &SrcExprResult,
                                     QualType DestType, bool CStyle,
                                     SourceRange OpRange, CastKind &Kind,
                                     CXXCastPath &BasePath, unsigned &msg) {
+  Expr *SrcExpr = SrcExprResult.get();
   // C++11 [expr.static.cast]p3:
   //   A glvalue of type "cv1 T1" can be cast to type "rvalue reference to
   //   cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1".
@@ -1633,12 +1635,6 @@ TryCastResult TryLValueToRValueCast(Sema &Self, Expr 
*SrcExpr,
   if (!SrcExpr->isGLValue())
     return TC_NotApplicable;
 
-  // A bit-field lvalue cannot be directly bound to an rvalue reference; it
-  // has no address.  Fall through to TryStaticImplicitCast so the initializer
-  // sequence materializes a temporary and binds to that instead.
-  if (SrcExpr->refersToBitField())
-    return TC_NotApplicable;
-
   // Because we try the reference downcast before this function, from now on
   // this is the only cast possibility, so we issue an error if we fail now.
   QualType FromType = SrcExpr->getType();
@@ -1662,6 +1658,16 @@ TryCastResult TryLValueToRValueCast(Sema &Self, Expr 
*SrcExpr,
     return TC_Failed;
   }
 
+  // C++ [expr.static.cast]p3:
+  //   If the value is not a bit-field, the result refers to the object or the
+  //   specified base class subobject thereof; otherwise, the lvalue-to-rvalue
+  //   conversion is applied to the bit-field and the resulting prvalue is used
+  //   as the operand of the static_cast for the remainder of this subclause.
+  if (SrcExpr->refersToBitField()) {
+    SrcExprResult = Self.DefaultLvalueConversion(SrcExpr);
+    return TC_NotApplicable;
+  }
+
   if (RefConv & Sema::ReferenceConversions::DerivedToBase) {
     Kind = CK_DerivedToBase;
     if (Self.CheckDerivedToBaseConversion(FromType, ToType,
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 6b02c943c343f..3f30e94aa8976 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -5800,11 +5800,8 @@ static void TryReferenceInitializationCore(Sema &S,
 
   //   [...] If T1 is reference-related to T2 and the reference is an rvalue
   //   reference, the initializer expression shall not be an lvalue.
-  //   However, a non-referenceable glvalue (bit-field, vector element, matrix
-  //   element) cannot be bound directly, so it is materialized into a
-  //   temporary regardless of value category — don't block it here.
   if (RefRelationship >= Sema::Ref_Related && !isLValueRef &&
-      InitCategory.isLValue() && !isNonReferenceableGLValue(Initializer)) {
+      InitCategory.isLValue()) {
     Sequence.SetFailed(
                     InitializationSequence::FK_RValueReferenceBindingToLValue);
     return;
diff --git a/clang/test/AST/ast-dump-rvalue-ref-bitfield.cpp 
b/clang/test/AST/ast-dump-rvalue-ref-bitfield.cpp
index 7d8ecec393d0a..5e2b994c3b239 100644
--- a/clang/test/AST/ast-dump-rvalue-ref-bitfield.cpp
+++ b/clang/test/AST/ast-dump-rvalue-ref-bitfield.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++11 -fsyntax-only \
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -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,
@@ -7,15 +7,9 @@
 
 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)'
+void test(A obj) {
 // CHECK:       VarDecl {{.*}} r 'int &&' cinit
 // CHECK-NEXT:  `-ExprWithCleanups {{.*}} 'int' xvalue
 // CHECK-NEXT:    `-CXXStaticCastExpr {{.*}} 'int' xvalue static_cast<int &&> 
<NoOp>
@@ -23,10 +17,15 @@ void test(A obj) {
 // CHECK-NEXT:        `-ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
 // CHECK-NEXT:          `-MemberExpr {{.*}} 'int' lvalue bitfield .a
 // CHECK-NEXT:            `-DeclRefExpr {{.*}} 'A' lvalue ParmVar {{.*}} 'obj' 
'A'
+  int &&r = static_cast<int &&>(obj.a);
+  
 // CHECK:       VarDecl {{.*}} cr 'const int &&' cinit
 // CHECK-NEXT:  `-ExprWithCleanups {{.*}} 'const int' xvalue
 // CHECK-NEXT:    `-CXXStaticCastExpr {{.*}} 'const int' xvalue 
static_cast<const int &&> <NoOp>
 // CHECK-NEXT:      `-MaterializeTemporaryExpr {{.*}} 'const int' xvalue 
extended by Var {{.*}} 'cr' 'const int &&'
-// CHECK-NEXT:        `-ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
-// CHECK-NEXT:          `-MemberExpr {{.*}} 'int' lvalue bitfield .a
-// CHECK-NEXT:            `-DeclRefExpr {{.*}} 'A' lvalue ParmVar {{.*}} 'obj' 
'A'
+// CHECK-NEXT:        `-ImplicitCastExpr {{.*}} 'const int' <NoOp>
+// CHECK-NEXT:          `-ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// CHECK-NEXT:            `-MemberExpr {{.*}} 'int' lvalue bitfield .a
+// CHECK-NEXT:              `-DeclRefExpr {{.*}} 'A' lvalue ParmVar {{.*}} 
'obj' 'A'
+  const int &&cr = static_cast<const int &&>(obj.a);
+}
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp 
b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
index e2349774ed73c..4b7bf31773c96 100644
--- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
@@ -227,6 +227,7 @@ namespace bitfields {
     const int & cir2 = (xvalue<IntBitfield>().i); // no-warning
     const int && cir3 = (xvalue<IntBitfield>().i); // no-warning
     const int && cir4 = move(lvalue<IntBitfield>()).i; // no-warning
+    const int && cir5 = (lvalue<IntBitfield>().i); // expected-error{{rvalue 
reference to type 'const int' cannot bind to lvalue of type 'int'}}
 
     const volatile int & cvir1 = (lvalue<IntBitfield>().i); // 
expected-error{{non-const reference cannot bind to bit-field 'i'}}
     const volatile int & cvir2 = (xvalue<IntBitfield>().i); // 
expected-error{{volatile lvalue reference to type 'const volatile int' cannot 
bind to a temporary of type 'int'}}
diff --git a/clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp 
b/clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp
index 7144d9c845a9d..7b25994b06d6a 100644
--- a/clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp
+++ b/clang/test/CodeGenCXX/rvalue-ref-bitfield.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown \
-// RUN:   -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown \
+// RUN:   -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
 
 // static_cast<T&&> of a bit-field lvalue materializes a temporary holding the
 // loaded bit-field value, and the reference binds to that temporary.
diff --git a/clang/test/SemaCXX/static-cast-bitfield-temporary.cpp 
b/clang/test/SemaCXX/static-cast-bitfield-temporary.cpp
new file mode 100644
index 0000000000000..847c53bed06fd
--- /dev/null
+++ b/clang/test/SemaCXX/static-cast-bitfield-temporary.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown -fsyntax-only 
-verify %s
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown -fsyntax-only 
-verify -fexperimental-new-constant-interpreter %s
+
+struct A {
+  unsigned x : 1;
+};
+
+constexpr unsigned f1() {
+  A a{0};
+  unsigned &&r = static_cast<unsigned &&>(a.x);
+  r = 7;
+  a.x = 0;
+  return r;
+}
+static_assert(f1() == 7);
+
+// FIXME: the temporary's lifetime should expire at the end of the
+// full-expression; reading through p after that point must be rejected.
+// Currently a different Sema error fires due to the direct bit-field binding.
+constexpr auto &q(auto &&a) { return a; } // expected-error {{non-const lvalue 
reference to type 'unsigned int' cannot bind to a temporary of type 'unsigned 
int'}}
+constexpr unsigned f2() {
+  A a{0};
+  unsigned *p;
+  *(p = &q(static_cast<unsigned &&>(a.x))) = 1; // expected-note {{in 
instantiation of function template specialization 'q<unsigned int>' requested 
here}}
+  // expected-note@-1 {{subexpression not valid in a constant expression}}
+  return *p;
+}
+static_assert(f2() == 1); // expected-error {{static assertion expression is 
not an integral constant expression}}
+                           // expected-note@-1 {{in call to 'f2()'}}
+                           
+constexpr unsigned f3() {
+  A a{0};
+  unsigned &&r = const_cast<unsigned &&>(static_cast<const unsigned &&>(a.x));
+  r = 0; // expected-note {{modification of object of const-qualified type 
'const unsigned int' is not allowed in a constant expression}}
+  return a.x;
+}
+static_assert(f3() == 0); // expected-error {{static assertion expression is 
not an integral constant expression}}
+                          // expected-note@-1 {{in call to 'f3()'}}
\ No newline at end of file

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

Reply via email to