summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2019-11-29 09:56:02 -0800
committerAkira Hatanaka <ahatanaka@apple.com>2019-12-03 23:44:30 -0800
commitd8136f14f125fb27f2326f397df0964bf62078ca (patch)
treee927eb6aa7e29cdaa30c2b90dab6258fc22ffae1 /clang
parentd08dc0655e74d5c226789e1a2378c7c215ee7297 (diff)
downloadbcm5719-llvm-d8136f14f125fb27f2326f397df0964bf62078ca.tar.gz
bcm5719-llvm-d8136f14f125fb27f2326f397df0964bf62078ca.zip
[CodeGen][ObjC] Emit a primitive store to store a __strong field in
ExpandTypeFromArgs This fixes a bug in IRGen where a call to `llvm.objc.storeStrong` was being emitted to initialize a __strong field of an uninitialized temporary struct, which caused crashes at runtime. rdar://problem/51807365
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp7
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp6
-rw-r--r--clang/test/CodeGenObjC/nontrivial-struct-param-init.m17
3 files changed, 28 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index f992f904fe7..ca6b1d409c2 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1047,8 +1047,13 @@ void CodeGenFunction::ExpandTypeFromArgs(
auto imagValue = *AI++;
EmitStoreOfComplex(ComplexPairTy(realValue, imagValue), LV, /*init*/ true);
} else {
+ // Call EmitStoreOfScalar except when the lvalue is a bitfield to emit a
+ // primitive store.
assert(isa<NoExpansion>(Exp.get()));
- EmitStoreThroughLValue(RValue::get(*AI++), LV);
+ if (LV.isBitField())
+ EmitStoreThroughLValue(RValue::get(*AI++), LV);
+ else
+ EmitStoreOfScalar(*AI++, LV);
}
}
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 6e3a26e2c78..cd42faefab0 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4544,7 +4544,11 @@ RValue CodeGenFunction::EmitRValueForField(LValue LV,
// don't load reference fields.
if (FD->getType()->isReferenceType())
return RValue::get(FieldLV.getPointer(*this));
- return EmitLoadOfLValue(FieldLV, Loc);
+ // Call EmitLoadOfScalar except when the lvalue is a bitfield to emit a
+ // primitive load.
+ if (FieldLV.isBitField())
+ return EmitLoadOfLValue(FieldLV, Loc);
+ return RValue::get(EmitLoadOfScalar(FieldLV, Loc));
}
llvm_unreachable("bad evaluation kind");
}
diff --git a/clang/test/CodeGenObjC/nontrivial-struct-param-init.m b/clang/test/CodeGenObjC/nontrivial-struct-param-init.m
new file mode 100644
index 00000000000..96a63b83ac7
--- /dev/null
+++ b/clang/test/CodeGenObjC/nontrivial-struct-param-init.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple i386-apple-watchos6.0-simulator -emit-llvm -fblocks -fobjc-arc -o - %s | FileCheck %s
+
+// CHECK: %[[STRUCT_S:.*]] = type { i8* }
+
+typedef struct {
+ id x;
+} S;
+
+// CHECK: define void @test0(i8* %[[A_0:.*]])
+// CHECK: %[[A:.*]] = alloca %[[STRUCT_S]], align 4
+// CHECK: %[[X:.*]] = getelementptr inbounds %[[STRUCT_S]], %[[STRUCT_S]]* %[[A]], i32 0, i32 0
+// CHECK: store i8* %[[A_0]], i8** %[[X]], align 4
+// CHECK: %[[V0:.*]] = bitcast %[[STRUCT_S]]* %[[A]] to i8**
+// CHECK: call void @__destructor_4_s0(i8** %[[V0]]) #2
+
+void test0(S a) {
+}
OpenPOWER on IntegriCloud