aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGObjC.cpp28
-rw-r--r--lib/CodeGen/CodeGenFunction.h1
-rw-r--r--test/CodeGenObjC/atomic-aggregate-property.m11
3 files changed, 32 insertions, 8 deletions
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index ffdcbdcdea..c40fe939b6 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -148,19 +148,21 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
const ObjCPropertyImplDecl *PID) {
ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
const ObjCPropertyDecl *PD = PID->getPropertyDecl();
+ bool IsAtomic =
+ !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
assert(OMD && "Invalid call to generate getter (empty method)");
// FIXME: This is rather murky, we create this here since they will not have
// been created by Sema for us.
OMD->createImplicitParams(getContext(), IMP->getClassInterface());
StartObjCMethod(OMD, IMP->getClassInterface());
-
+
// Determine if we should use an objc_getProperty call for
// this. Non-atomic properties are directly evaluated.
// atomic 'copy' and 'retain' properties are also directly
// evaluated in gc-only mode.
if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
- !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
+ IsAtomic &&
(PD->getSetterKind() == ObjCPropertyDecl::Copy ||
PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
llvm::Value *GetPropertyFn =
@@ -208,7 +210,8 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
StoreComplexToAddr(Pair, ReturnValue, LV.isVolatileQualified());
}
else if (hasAggregateLLVMType(Ivar->getType())) {
- if (!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic)
+ bool IsStrong = false;
+ if ((IsAtomic || (IsStrong = IvarTypeWithAggrGCObjects(Ivar->getType())))
&& CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect
&& CGM.getObjCRuntime().GetCopyStructFunction()) {
llvm::Value *GetCopyStructFn =
@@ -232,12 +235,15 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
// FIXME. Implement when Atomic is false; But when struct has
// gc'able data member!
llvm::Value *isAtomic =
- llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
+ llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy),
+ IsAtomic ? 1 : 0);
Args.push_back(std::make_pair(RValue::get(isAtomic),
getContext().BoolTy));
- llvm::Value *False =
- llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0);
- Args.push_back(std::make_pair(RValue::get(False), getContext().BoolTy));
+ llvm::Value *hasStrong =
+ llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy),
+ IsStrong ? 1 : 0);
+ Args.push_back(std::make_pair(RValue::get(hasStrong),
+ getContext().BoolTy));
EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
FunctionType::ExtInfo()),
GetCopyStructFn, ReturnValueSlot(), Args);
@@ -396,6 +402,14 @@ bool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
return (AI.getKind() == ABIArgInfo::Indirect);
}
+bool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) {
+ if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
+ return false;
+ if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>())
+ return FDTTy->getDecl()->hasObjectMember();
+ return false;
+}
+
llvm::Value *CodeGenFunction::LoadObjCSelf() {
const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
// See if we need to lazily forward self inside a block literal.
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 10f100d3f4..793b988f04 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -480,6 +480,7 @@ public:
void GenerateObjCSetter(ObjCImplementationDecl *IMP,
const ObjCPropertyImplDecl *PID);
bool IndirectObjCSetterArg(const CGFunctionInfo &FI);
+ bool IvarTypeWithAggrGCObjects(QualType Ty);
//===--------------------------------------------------------------------===//
// Block Bits
diff --git a/test/CodeGenObjC/atomic-aggregate-property.m b/test/CodeGenObjC/atomic-aggregate-property.m
index 66762c436f..2896d379e7 100644
--- a/test/CodeGenObjC/atomic-aggregate-property.m
+++ b/test/CodeGenObjC/atomic-aggregate-property.m
@@ -1,19 +1,28 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -emit-llvm -o - %s | FileCheck -check-prefix LP64 %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fobjc-gc -emit-llvm -o - %s | FileCheck -check-prefix LP64 %s
// rdar: // 7849824
struct s {
double a, b, c, d;
};
+struct s1 {
+ int i;
+ id j;
+ id k;
+};
+
@interface A
@property (readwrite) double x;
@property (readwrite) struct s y;
+@property (nonatomic, readwrite) struct s1 z;
@end
@implementation A
@synthesize x;
@synthesize y;
+@synthesize z;
@end
// CHECK-LP64: call void @objc_copyStruct
// CHECK-LP64: call void @objc_copyStruct
+// CHECK-LP64: call void @objc_copyStruct