From 7c731f5ac7b995fe57c4bda87ed5f59c58a33eb5 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Thu, 30 May 2013 18:12:23 +0000 Subject: [PATCH] Do not reuse the debug location of the return value's store if there is autorelease code to be emitted between store and return instructions. This is analoguous to what we do for lexical scope cleanups. rdar://problem/13977888 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182947 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCall.cpp | 6 ++- test/CodeGenObjC/arc-linetable-autorelease.m | 40 ++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 test/CodeGenObjC/arc-linetable-autorelease.m diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 1ea16fe13a..9a8edccdef 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1667,8 +1667,10 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, // If there is a dominating store to ReturnValue, we can elide // the load, zap the store, and usually zap the alloca. if (llvm::StoreInst *SI = findDominatingStoreToReturnValue(*this)) { - // Reuse the debug location from the store unless we're told not to. - if (EmitRetDbgLoc) + // Reuse the debug location from the store unless there is + // cleanup code to be emitted between the store and return + // instruction. + if (EmitRetDbgLoc && !AutoreleaseResult) RetDbgLoc = SI->getDebugLoc(); // Get the stored value and nuke the now-dead store. RV = SI->getValueOperand(); diff --git a/test/CodeGenObjC/arc-linetable-autorelease.m b/test/CodeGenObjC/arc-linetable-autorelease.m new file mode 100644 index 0000000000..be05ec2fcd --- /dev/null +++ b/test/CodeGenObjC/arc-linetable-autorelease.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -emit-llvm -fobjc-arc -g -triple x86_64-apple-darwin10 %s -o - | FileCheck %s +// Ensure that the line info is making sense: +// ARC cleanups should be at the closing '}'. +@protocol NSObject +@end + +@interface NSObject {} +@end + +@protocol NSCopying +@end + +@protocol NSCoding +@end + +typedef double CGFloat; +struct CGRect {}; +typedef struct CGRect CGRect; +typedef CGRect NSRect; +NSRect NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h); +@interface NSBezierPath : NSObject ++ (NSBezierPath *)bezierPathWithRoundedRect:(NSRect)rect xRadius:(CGFloat)xRadius yRadius:(CGFloat)yRadius; +@end +@implementation AppDelegate : NSObject {} +- (NSBezierPath *)_createBezierPathWithWidth:(CGFloat)width height:(CGFloat)height radius:(CGFloat)radius lineWidth:(CGFloat)lineWidth +{ + NSRect rect = NSMakeRect(0, 0, width, height); + NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:rect xRadius:radius yRadius:radius]; + CGFloat pattern[2]; + // CHECK: define {{.*}}_createBezierPathWithWidth + // CHECK: load {{.*}} %path, align {{.*}}, !dbg ![[RET:[0-9]+]] + // CHECK: call void @objc_storeStrong{{.*}} !dbg ![[ARC1:[0-9]+]] + // CHECK: call {{.*}} @objc_autoreleaseReturnValue{{.*}} !dbg ![[ARC2:[0-9]+]] + // CHECK: ret {{.*}} !dbg ![[ARC2]] + // CHECK: ![[RET]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} + return path; + // CHECK: ![[ARC1]] = metadata !{i32 [[@LINE+2]], i32 0, metadata !{{.*}}, null} + // CHECK: ![[ARC2]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null} +} +@end -- 2.50.1