r207480 - Debug info: Improve line table for functions with cleanups an early exit

Adrian Prantl aprantl at apple.com
Mon Apr 28 18:08:00 PDT 2014


Author: adrian
Date: Mon Apr 28 20:07:59 2014
New Revision: 207480

URL: http://llvm.org/viewvc/llvm-project?rev=207480&view=rev
Log:
Debug info: Improve line table for functions with cleanups an early exit
and no return expr at the end of the function.
The "function has only simple returns" check in FinishFunction tests
whether the number of simple return exprs equals the number of return
exprs, but so far a fallthrough at the end of a function was not counted
as a return, which would result in cleanup code being associated with the
wrong source line.

rdar://problem/16733984.

Modified:
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/test/CodeGenObjC/arc-linetable.m

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=207480&r1=207479&r2=207480&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Mon Apr 28 20:07:59 2014
@@ -498,6 +498,22 @@ void CodeGenFunction::EmitOpenCLKernelMe
   OpenCLKernelMetadata->addOperand(kernelMDNode);
 }
 
+/// Determine whether the function F ends with a return stmt.
+static bool endsWithReturn(const Decl* F) {
+  const Stmt *Body = nullptr;
+  if (auto *FD = dyn_cast_or_null<FunctionDecl>(F))
+    Body = FD->getBody();
+  else if (auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(F))
+    Body = OMD->getBody();
+
+  if (auto *CS = dyn_cast_or_null<CompoundStmt>(Body)) {
+    auto LastStmt = CS->body_rbegin();
+    if (LastStmt != CS->body_rend())
+      return isa<ReturnStmt>(*LastStmt);
+  }
+  return false;
+}
+
 void CodeGenFunction::StartFunction(GlobalDecl GD,
                                     QualType RetTy,
                                     llvm::Function *Fn,
@@ -593,6 +609,10 @@ void CodeGenFunction::StartFunction(Glob
   if (RetTy->isVoidType()) {
     // Void type; nothing to return.
     ReturnValue = 0;
+
+    // Count the implicit return.
+    if (!endsWithReturn(D))
+      ++NumReturnExprs;
   } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
              !hasScalarEvaluationKind(CurFnInfo->getReturnType())) {
     // Indirect aggregate return; emit returned value directly into sret slot.

Modified: cfe/trunk/test/CodeGenObjC/arc-linetable.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-linetable.m?rev=207480&r1=207479&r2=207480&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-linetable.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-linetable.m Mon Apr 28 20:07:59 2014
@@ -32,6 +32,15 @@
 // CHECK: @objc_msgSend{{.*}} !dbg ![[MSG7:[0-9]+]]
 // CHECK: ret {{.*}} !dbg ![[RET7:[0-9]+]]
 
+// CHECK: define {{.*}}testCleanupVoid
+// CHECK: icmp ne {{.*}}!dbg ![[SKIP1:[0-9]+]]
+// CHECK-NEXT: br {{.*}}, label %[[CLEANUP:.*]], label
+// CHECK: [[CLEANUP]]:
+// CHECK-NEXT: !dbg ![[RET8:[0-9]+]]
+// CHECK: @objc_storeStrong{{.*}}, !dbg ![[ARC8:[0-9]+]]
+// CHECK: ret {{.*}} !dbg ![[RET8]]
+
+typedef signed char BOOL;
 
 @interface NSObject
 + (id)alloc;
@@ -93,6 +102,22 @@
   return 1;
 }
 
+- (void)testCleanupVoid:(BOOL)skip withDelegate: (AppDelegate *) delegate {
+  static BOOL skip_all;
+  // CHECK: ![[SKIP1]] = metadata !{i32 [[@LINE+1]], i32 0,
+  if (!skip_all) {
+    if (!skip) {
+      return;
+    }
+    NSString *s = @"bar";
+    if (!skip) {
+      [delegate testVoid :s];
+    }
+  }
+  // CHECK: ![[RET8]] = metadata !{i32 [[@LINE+2]], i32 0,
+  // CHECK: ![[ARC8]] = metadata !{i32 [[@LINE+1]], i32 0,
+}
+
 
 @end
 





More information about the cfe-commits mailing list