aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGExpr.cpp6
-rw-r--r--test/CodeGen/bitfield-2.c16
2 files changed, 21 insertions, 1 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index d338a49d2c..68f09e2d29 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -792,11 +792,15 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
const CGBitFieldInfo &Info = Dst.getBitFieldInfo();
// Get the output type.
- const llvm::Type *ResLTy = ConvertType(Ty);
+ const llvm::Type *ResLTy = ConvertTypeForMem(Ty);
unsigned ResSizeInBits = CGM.getTargetData().getTypeSizeInBits(ResLTy);
// Get the source value, truncated to the width of the bit-field.
llvm::Value *SrcVal = Src.getScalarVal();
+
+ if (Ty->isBooleanType())
+ SrcVal = Builder.CreateIntCast(SrcVal, ResLTy, /*IsSigned=*/false);
+
SrcVal = Builder.CreateAnd(SrcVal, llvm::APInt::getLowBitsSet(ResSizeInBits,
Info.getSize()),
"bf.value");
diff --git a/test/CodeGen/bitfield-2.c b/test/CodeGen/bitfield-2.c
index 79033d7f7b..94f275d7d5 100644
--- a/test/CodeGen/bitfield-2.c
+++ b/test/CodeGen/bitfield-2.c
@@ -205,3 +205,19 @@ unsigned long long test_5() {
res ^= g5.f0 ^ g5.f1 ^ g5.f2;
return res;
}
+
+struct A {
+ _Bool b : 2;
+};
+
+// CHECK-OPT: define zeroext i1 @test_6()
+// CHECK-OPT: ret i1 true
+// CHECK-OPT: }
+_Bool test_6() {
+ struct A a;
+
+ a.b = (_Bool)0;
+
+ return (a.b = !a.b);
+}
+