From 004e95174d0161ba92ca7e0f055462a2aeef05fa Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Tue, 27 Jun 2017 18:37:51 +0000 Subject: [PATCH] CodeGen: load indirect ObjC ARC arguments in prologue When generating a prologue, add loads for ARC arguments passed indirectly. Patch by Dave Lee! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@306444 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDecl.cpp | 4 ++++ test/CodeGenObjCXX/arc-indirect.mm | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 test/CodeGenObjCXX/arc-indirect.mm diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index ccd3b8d513..4b656ea4a8 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -1860,6 +1860,10 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, lt = Qualifiers::OCL_ExplicitNone; } + // Load objects passed indirectly. + if (Arg.isIndirect() && !ArgVal) + ArgVal = Builder.CreateLoad(DeclPtr); + if (lt == Qualifiers::OCL_Strong) { if (!isConsumed) { if (CGM.getCodeGenOpts().OptimizationLevel == 0) { diff --git a/test/CodeGenObjCXX/arc-indirect.mm b/test/CodeGenObjCXX/arc-indirect.mm new file mode 100644 index 0000000000..2684e82e2e --- /dev/null +++ b/test/CodeGenObjCXX/arc-indirect.mm @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++11 -triple i686-unknown-windows-msvc -fobjc-runtime=gnustep -fobjc-arc -Wno-objc-root-class -emit-llvm -o - %s | FileCheck -check-prefixes CHECK,CHECK-GNUSTEP %s +// RUN: %clang_cc1 -std=c++11 -triple i686-unknown-windows-msvc -fobjc-runtime=macosx -fobjc-arc -Wno-objc-root-class -emit-llvm -o - %s | FileCheck -check-prefixes CHECK,CHECK-DARWIN %s +// RUN: %clang_cc1 -std=c++11 -triple i686-unknown-windows-msvc -fobjc-runtime=ios -fobjc-arc -Wno-objc-root-class -emit-llvm -o - %s | FileCheck -check-prefixes CHECK,CHECK-DARWIN %s + +// non trivially copyable, forces inalloca +struct S { + S(const S &s) {} +}; + +@interface C +@end +@implementation C +- (void)object:(id)obj struct:(S)s { +} +@end + +// CHECK-GNUSTEP: define internal void @_i_C__object_struct_(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* inalloca) +// CHECK-DARWIN: define internal void @"\01-[C object:struct:]"(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* inalloca) +// CHECK: %obj = getelementptr inbounds <{ %0*, i8*, i8*, %struct.S, [3 x i8] }>, <{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* %0, i32 0, i32 2 +// CHECK: %1 = load i8*, i8** %obj, align 4 +// CHECK: call void @objc_storeStrong(i8** %obj, i8* %1) -- 2.40.0