From 71309be80a246a2f06842bd32ee53b3d5f007b82 Mon Sep 17 00:00:00 2001 From: John McCall Date: Sat, 26 Feb 2011 09:12:15 +0000 Subject: [PATCH] Zero-initialize the struct-return slot of an Objective-C message send before making the call. Fixes rdar://problem/7854674 llvm-svn: 126543 --- clang/lib/CodeGen/CGObjCMac.cpp | 2 ++ clang/test/CodeGenObjC/messages-2.m | 23 +++++++++++++++++++- clang/test/CodeGenObjC/messages.m | 33 +++++++++++++++++++++++------ 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 7c679b90590c..f5befceb0fc8 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/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/clang/test/CodeGenObjC/messages-2.m b/clang/test/CodeGenObjC/messages-2.m index 05e30ab131a5..5ef2261b1983 100644 --- a/clang/test/CodeGenObjC/messages-2.m +++ b/clang/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/clang/test/CodeGenObjC/messages.m b/clang/test/CodeGenObjC/messages.m index 5f77a8e327eb..b36fe5b644ed 100644 --- a/clang/test/CodeGenObjC/messages.m +++ b/clang/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]; }