Author: Benjamin Stott
Date: 2025-11-19T11:41:06-08:00
New Revision: 60a27953eabe3a0ded7c9b7b7786dfd1fe5d8c5f

URL: 
https://github.com/llvm/llvm-project/commit/60a27953eabe3a0ded7c9b7b7786dfd1fe5d8c5f
DIFF: 
https://github.com/llvm/llvm-project/commit/60a27953eabe3a0ded7c9b7b7786dfd1fe5d8c5f.diff

LOG: [Clang][CodeGen] Use EmitLoadOfLValue instead of EmitLoadOfScalar to get 
LHS for complex compound assignment (#166798)

- Fixes https://github.com/llvm/llvm-project/issues/166512
- `ComplexExprEmitter::EmitCompoundAssignLValue` is calling
`EmitLoadOfScalar(LValue, SourceLocation)` to load the LHS value in the
case that it's non-complex, however this function requires that the
value is a simple LValue - issue occurred because the LValue in question
was a bitfield LValue. I changed it to use this function which seems to
handle all of the different cases (deferring to the original
`EmitLoadOfScalar` if it's a simple LValue)

Added: 
    clang/test/CodeGen/complex-compound-assign-bitfield.c

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/CodeGen/CGExprComplex.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7e9119b5f2b46..0746fa93209d3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -484,6 +484,7 @@ Bug Fixes in This Version
 - Fixed a failed assertion with empty filename in ``#embed`` directive. 
(#GH162951)
 - Fixed a crash triggered by unterminated ``__has_embed``. (#GH162953)
 - Accept empty enumerations in MSVC-compatible C mode. (#GH114402)
+- Fix a bug leading to incorrect code generation with complex number compound 
assignment and bitfield values, which also caused a crash with UBsan. 
(#GH166798)
 - Fixed false-positive shadow diagnostics for lambdas in explicit object 
member functions. (#GH163731)
 
 Bug Fixes to Compiler Builtins

diff  --git a/clang/lib/CodeGen/CGExprComplex.cpp 
b/clang/lib/CodeGen/CGExprComplex.cpp
index f8a946a76554a..d281c4c20616a 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -1283,7 +1283,7 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
     else
       OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
   } else {
-    llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, Loc);
+    llvm::Value *LHSVal = CGF.EmitLoadOfLValue(LHS, Loc).getScalarVal();
     // For floating point real operands we can directly pass the scalar form
     // to the binary operator emission and potentially get more efficient code.
     if (LHSTy->isRealFloatingType()) {
@@ -1318,7 +1318,7 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
   } else {
     llvm::Value *ResVal =
         CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy, Loc);
-    CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false);
+    CGF.EmitStoreThroughLValue(RValue::get(ResVal), LHS, /*isInit*/ false);
     Val = RValue::get(ResVal);
   }
 

diff  --git a/clang/test/CodeGen/complex-compound-assign-bitfield.c 
b/clang/test/CodeGen/complex-compound-assign-bitfield.c
new file mode 100644
index 0000000000000..e705bff22e67d
--- /dev/null
+++ b/clang/test/CodeGen/complex-compound-assign-bitfield.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -std=c23 -emit-llvm -o 
- | FileCheck %s
+
+struct Bits {
+    int pad1: 30;
+    bool b: 1;
+    int pad2: 1;
+};
+
+int main(void) {
+// CHECK-LABEL: define dso_local i32 @main() #0 {
+    struct Bits x;
+    x.b += __builtin_complex(-1.0f, 0.0f);
+// CHECK: %bf.load = load i32, ptr %x, align 4
+// CHECK-NEXT: %bf.lshr = lshr i32 %bf.load, 30
+// CHECK-NEXT: %bf.clear = and i32 %bf.lshr, 1
+// CHECK-NEXT: %bf.cast = trunc i32 %bf.clear to i1
+// CHECK-NEXT: %conv = uitofp i1 %bf.cast to float
+
+// CHECK: %0 = zext i1 %tobool1 to i32
+// CHECK-NEXT: %bf.load2 = load i32, ptr %x, align 4
+// CHECK-NEXT: %bf.shl = shl i32 %0, 30
+// CHECK-NEXT: %bf.clear3 = and i32 %bf.load2, -1073741825
+// CHECK-NEXT: %bf.set = or i32 %bf.clear3, %bf.shl
+// CHECK-NEXT: store i32 %bf.set, ptr %x, align 4
+}


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

Reply via email to