From: John McCall Date: Sat, 26 Feb 2011 09:12:15 +0000 (+0000) Subject: Zero-initialize the struct-return slot of an Objective-C message X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a1bcc4ddb1ed8be9be6950232941d80a04f80819;p=clang Zero-initialize the struct-return slot of an Objective-C message send before making the call. Fixes rdar://problem/7854674 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126543 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 7c679b9059..f5befceb0f 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -1639,6 +1639,7 @@ CGObjCCommonMac::EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF, llvm::Constant *Fn = NULL; if (CGM.ReturnTypeUsesSRet(FnInfo)) { + CGF.EmitNullInitialization(Return.getValue(), ResultType); Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper) : ObjCTypes.getSendStretFn(IsSuper); } else if (CGM.ReturnTypeUsesFPRet(ResultType)) { @@ -5629,6 +5630,7 @@ CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend( llvm::Constant *Fn = 0; std::string Name("\01l_"); if (CGM.ReturnTypeUsesSRet(FnInfo)) { + CGF.EmitNullInitialization(Return.getValue(), ResultType); if (IsSuper) { Fn = ObjCTypes.getMessageSendSuper2StretFixupFn(); Name += "objc_msgSendSuper2_stret_fixup"; diff --git a/test/CodeGenObjC/messages-2.m b/test/CodeGenObjC/messages-2.m index 05e30ab131..5ef2261b19 100644 --- a/test/CodeGenObjC/messages-2.m +++ b/test/CodeGenObjC/messages-2.m @@ -1,4 +1,7 @@ -// RUN: %clang_cc1 -emit-llvm -o %t %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NF + +// Most of this test is apparently just verifying that we don't crash. int printf(const char *, ...); @@ -140,3 +143,21 @@ typedef struct { return 5; } @end + +// rdar://problem/7854674 +// CHECK: define void @test0([[A:%.*]]* +// CHECK-NF: define void @test0([[A:%.*]]* +void test0(A *a) { + // CHECK: alloca [[A]]* + // CHECK-NEXT: [[POINT:%.*]] = alloca [[POINT_T:%.*]], + // CHECK-NF: alloca [[A]]* + // CHECK-NF-NEXT: [[POINT:%.*]] = alloca [[POINT_T:%.*]], + + // CHECK: [[T0:%.*]] = bitcast [[POINT_T]]* [[POINT]] to i8* + // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 48, i32 4, i1 false) + // CHECK-NEXT: call {{.*}} @objc_msgSend_stret to + // CHECK-NF: [[T0:%.*]] = bitcast [[POINT_T]]* [[POINT]] to i8* + // CHECK-NF-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 48, i32 4, i1 false) + // CHECK-NF-NEXT: call {{.*}} @objc_msgSend_stret to + MyPoint point = [a returnAPoint]; +} diff --git a/test/CodeGenObjC/messages.m b/test/CodeGenObjC/messages.m index 5f77a8e327..b36fe5b644 100644 --- a/test/CodeGenObjC/messages.m +++ b/test/CodeGenObjC/messages.m @@ -1,9 +1,7 @@ -// RUN: %clang_cc1 -emit-llvm -o %t %s -// RUN: grep "objc_msgSend" %t | count 6 -// RUN: %clang_cc1 -fgnu-runtime -emit-llvm -o %t %s -// RUN: grep "objc_msg_lookup" %t | count 6 -// RUN: %clang_cc1 -fgnu-runtime -fobjc-nonfragile-abi -emit-llvm -o %t %s -// RUN: grep "objc_msg_lookup_sender" %t | count 6 +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-MAC +// RUN: %clang_cc1 -emit-llvm -fobjc-nonfragile-abi -o - %s | FileCheck %s -check-prefix=CHECK-MAC-NF +// RUN: %clang_cc1 -fgnu-runtime -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-GNU +// RUN: %clang_cc1 -fgnu-runtime -fobjc-nonfragile-abi -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-GNU-NF typedef struct { int x; @@ -15,12 +13,35 @@ void f0(id a) { int i; MyPoint pt = { 1, 2}; + // CHECK-MAC: call {{.*}} @objc_msgSend( + // CHECK-MAC-NF: call {{.*}} @objc_msgSend( + // CHECK-GNU: call {{.*}} @objc_msg_lookup( + // CHECK-GNU-NF: call {{.*}} @objc_msg_lookup_sender( [a print0]; + + // CHECK-MAC: call {{.*}} @objc_msgSend to + // CHECK-MAC-NF: call {{.*}} @objc_msgSend to + // CHECK-GNU: call {{.*}} @objc_msg_lookup to + // CHECK-GNU-NF: call {{.*}} @objc_msg_lookup_sender to [a print1: 10]; + + // CHECK-MAC: call {{.*}} @objc_msgSend to + // CHECK-MAC-NF: call {{.*}} @objc_msgSend to + // CHECK-GNU: call {{.*}} @objc_msg_lookup to + // CHECK-GNU-NF: call {{.*}} @objc_msg_lookup_sender to [a print2: 10 and: "hello" and: 2.2]; + + // CHECK-MAC: call {{.*}} @objc_msgSend to + // CHECK-MAC-NF: call {{.*}} @objc_msgSend to + // CHECK-GNU: call {{.*}} @objc_msg_lookup to + // CHECK-GNU-NF: call {{.*}} @objc_msg_lookup_sender to [a takeStruct: pt ]; void *s = @selector(print0); for (i=0; i<2; ++i) + // CHECK-MAC: call {{.*}} @objc_msgSend to + // CHECK-MAC-NF: call {{.*}} @objc_msgSend to + // CHECK-GNU: call {{.*}} @objc_msg_lookup to + // CHECK-GNU-NF: call {{.*}} @objc_msg_lookup_sender to [a performSelector:s]; }