r261151 - [CodeGen] Fix an assert in CodeGenFunction::EmitFunctionEpilog

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 17 13:09:50 PST 2016


Author: ahatanak
Date: Wed Feb 17 15:09:50 2016
New Revision: 261151

URL: http://llvm.org/viewvc/llvm-project?rev=261151&view=rev
Log:
[CodeGen] Fix an assert in CodeGenFunction::EmitFunctionEpilog

The assert is triggered because isObjCRetainableType() is called on the
canonicalized return type that has been stripped of the typedefs and
attributes attached to it. To fix this assert, this commit gets the
original return type from CurCodeDecl or BlockInfo and uses it instead
of the canoicalized type.

rdar://problem/24470031

Differential Revision: http://reviews.llvm.org/D16914

Added:
    cfe/trunk/test/CodeGenObjCXX/auto-release-result-assert.mm
Modified:
    cfe/trunk/lib/CodeGen/CGCall.cpp

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=261151&r1=261150&r2=261151&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Wed Feb 17 15:09:50 2016
@@ -14,6 +14,7 @@
 
 #include "CGCall.h"
 #include "ABIInfo.h"
+#include "CGBlocks.h"
 #include "CGCXXABI.h"
 #include "CGCleanup.h"
 #include "CodeGenFunction.h"
@@ -2462,9 +2463,26 @@ void CodeGenFunction::EmitFunctionEpilog
     // In ARC, end functions that return a retainable type with a call
     // to objc_autoreleaseReturnValue.
     if (AutoreleaseResult) {
+#ifndef NDEBUG
+      // Type::isObjCRetainabletype has to be called on a QualType that hasn't
+      // been stripped of the typedefs, so we cannot use RetTy here. Get the
+      // original return type of FunctionDecl, CurCodeDecl, and BlockDecl from
+      // CurCodeDecl or BlockInfo.
+      QualType RT;
+
+      if (auto *FD = dyn_cast<FunctionDecl>(CurCodeDecl))
+        RT = FD->getReturnType();
+      else if (auto *MD = dyn_cast<ObjCMethodDecl>(CurCodeDecl))
+        RT = MD->getReturnType();
+      else if (isa<BlockDecl>(CurCodeDecl))
+        RT = BlockInfo->BlockExpression->getFunctionType()->getReturnType();
+      else
+        llvm_unreachable("Unexpected function/method type");
+
       assert(getLangOpts().ObjCAutoRefCount &&
              !FI.isReturnsRetained() &&
-             RetTy->isObjCRetainableType());
+             RT->isObjCRetainableType());
+#endif
       RV = emitAutoreleaseOfResult(*this, RV);
     }
 

Added: cfe/trunk/test/CodeGenObjCXX/auto-release-result-assert.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/auto-release-result-assert.mm?rev=261151&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/auto-release-result-assert.mm (added)
+++ cfe/trunk/test/CodeGenObjCXX/auto-release-result-assert.mm Wed Feb 17 15:09:50 2016
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -o - %s | FileCheck %s
+
+// CHECK-LABEL: define %struct.S1* @_Z4foo1i(
+// CHECK: %[[CALL:[a-z0-9]+]] = call %struct.S1* @_Z4foo0i
+// CHECK: ret %struct.S1* %[[CALL]]
+
+// CHECK-LABEL: define %struct.S1* @_ZN2S22m1Ev(
+// CHECK: %[[CALL:[a-z0-9]+]] = call %struct.S1* @_Z4foo0i
+// CHECK: ret %struct.S1* %[[CALL]]
+
+// CHECK-LABEL: define internal %struct.S1* @Block1_block_invoke(
+// CHECK: %[[CALL:[a-z0-9]+]] = call %struct.S1* @_Z4foo0i
+// CHECK: ret %struct.S1* %[[CALL]]
+
+struct S1;
+
+typedef __attribute__((NSObject)) struct __attribute__((objc_bridge(id))) S1 * S1Ref;
+
+S1Ref foo0(int);
+
+struct S2 {
+  S1Ref m1();
+};
+
+S1Ref foo1(int a) {
+  return foo0(a);
+}
+
+S1Ref S2::m1() {
+  return foo0(0);
+}
+
+S1Ref (^Block1)(void) = ^{
+  return foo0(0);
+};




More information about the cfe-commits mailing list