From: Nico Weber Date: Wed, 25 May 2016 14:15:08 +0000 (+0000) Subject: Fix mangled name of method with ns_consumed parameters. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5c9885d453be4a1239730fd1362305e48f554c9b;p=clang Fix mangled name of method with ns_consumed parameters. When a function/method use a parameter with "ns_consumed" attribute, ensure that the mangled name is the same whether -fobjc-arc is used or not. Since "ns_consumed" attribute is generally used to inform ARC that a function/method does sink the reference, it mean it is usually implemented in a compilation unit compiled without -fobjc-arc but used form a compilation unit compiled with it. Originally found while trying to use "ns_consumed" attribute in an Objective-C++ file in Chromium (http://crbug.com/599980) where it caused a linker error. Regression introduced by revision 262278 (previously the attribute was incorrectly not part of the mangled name). Patch from Sylvain Defresne ! http://reviews.llvm.org/D20113 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@270702 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 8d12105c71..1d40d42c11 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -2243,7 +2243,7 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionProtoType *Proto, FunctionTypeDepth.enterResultType(); // Mangle ns_returns_retained as an order-sensitive qualifier here. - if (Proto->getExtInfo().getProducesResult()) + if (Proto->getExtInfo().getProducesResult() && FD == nullptr) mangleVendorQualifier("ns_returns_retained"); // Mangle the return type without any direct ARC ownership qualifiers. @@ -2269,7 +2269,7 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionProtoType *Proto, assert(!FD || FD->getNumParams() == Proto->getNumParams()); for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) { // Mangle extended parameter info as order-sensitive qualifiers here. - if (Proto->hasExtParameterInfos()) { + if (Proto->hasExtParameterInfos() && FD == nullptr) { mangleExtParameterInfo(Proto->getExtParameterInfo(I)); } @@ -3819,7 +3819,7 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A) { Out << 'L'; // References to external entities use the mangled name; if the name would - // not normally be manged then mangle it as unqualified. + // not normally be mangled then mangle it as unqualified. mangle(D); Out << 'E'; diff --git a/test/CodeGenObjCXX/arc-attrs.mm b/test/CodeGenObjCXX/arc-attrs.mm index d571677719..0f0610f172 100644 --- a/test/CodeGenObjCXX/arc-attrs.mm +++ b/test/CodeGenObjCXX/arc-attrs.mm @@ -12,7 +12,7 @@ void sanityTest() { id x = makeObject1(); // CHECK-NEXT: [[OBJ2:%.*]] = call i8* @_Z11makeObject2v() - // CHECK-NEXT: call void @_Z13releaseObjectU11ns_consumedP11objc_object(i8* [[OBJ2]]) + // CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(i8* [[OBJ2]]) releaseObject(makeObject2()); // CHECK-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) @@ -31,16 +31,16 @@ void releaseObjectT(__attribute__((ns_consumed)) T); // CHECK-LABEL: define void @_Z12templateTestv void templateTest() { // CHECK: [[X:%.*]] = alloca i8*, align 8 - // CHECK-NEXT: [[OBJ1:%.*]] = call i8* @_Z12makeObjectT1IU8__strongP11objc_objectEU19ns_returns_retainedT_v() + // CHECK-NEXT: [[OBJ1:%.*]] = call i8* @_Z12makeObjectT1IU8__strongP11objc_objectET_v() // CHECK-NEXT: store i8* [[OBJ1]], i8** [[X]], align 8 id x = makeObjectT1(); - // CHECK-NEXT: [[OBJ2:%.*]] = call i8* @_Z12makeObjectT2IU8__strongP11objc_objectEU19ns_returns_retainedT_v() - // CHECK-NEXT: call void @_Z13releaseObjectU11ns_consumedP11objc_object(i8* [[OBJ2]]) + // CHECK-NEXT: [[OBJ2:%.*]] = call i8* @_Z12makeObjectT2IU8__strongP11objc_objectET_v() + // CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(i8* [[OBJ2]]) releaseObject(makeObjectT2()); // CHECK-NEXT: [[OBJ3:%.*]] = call i8* @_Z11makeObject1v() - // CHECK-NEXT: call void @_Z14releaseObjectTIU8__strongP11objc_objectEvU11ns_consumedT_(i8* [[OBJ3]]) + // CHECK-NEXT: call void @_Z14releaseObjectTIU8__strongP11objc_objectEvT_(i8* [[OBJ3]]) releaseObjectT(makeObject1()); // CHECK-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) diff --git a/test/CodeGenObjCXX/arc-mangle.mm b/test/CodeGenObjCXX/arc-mangle.mm index 84acbdb144..82e37556ec 100644 --- a/test/CodeGenObjCXX/arc-mangle.mm +++ b/test/CodeGenObjCXX/arc-mangle.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -triple %itanium_abi_triple -emit-llvm -fblocks -o - %s | FileCheck %s // CHECK-LABEL: define {{.*}}void @_Z1fPU8__strongP11objc_object(i8**) void f(__strong id *) {} @@ -18,10 +18,14 @@ void f(const __autoreleasing id *) {} void f(const __unsafe_unretained id *) {} // CHECK-LABEL: define {{.*}}void @_Z1fPFU19ns_returns_retainedP11objc_objectvE void f(__attribute__((ns_returns_retained)) id (*fn)()) {} +// CHECK-LABEL: define {{.*}}void @_Z1fP11objc_object +void f(__attribute__((ns_consumed)) id) {} // CHECK-LABEL: define {{.*}}void @_Z1fPFP11objc_objectU11ns_consumedS0_S0_E void f(id (*fn)(__attribute__((ns_consumed)) id, id)) {} // CHECK-LABEL: define {{.*}}void @_Z1fPFP11objc_objectS0_U11ns_consumedS0_E void f(__strong id (*fn)(id, __attribute__((ns_consumed)) id)) {} +// CHECK-LABEL: define {{.*}}void @_Z1fU13block_pointerFvU11ns_consumedP11objc_objectE +void f(void (^)(__attribute__((ns_consumed)) id)) {} template struct unsigned_c { }; diff --git a/test/CodeGenObjCXX/mangle.mm b/test/CodeGenObjCXX/mangle.mm index bcb920ba1e..2854cffc94 100644 --- a/test/CodeGenObjCXX/mangle.mm +++ b/test/CodeGenObjCXX/mangle.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -fblocks -o - | FileCheck %s // CHECK: @"_ZZ11+[A shared]E1a" = internal global // CHECK: @"_ZZ11-[A(Foo) f]E1a" = internal global @@ -113,3 +113,10 @@ void parameterized_test2(__kindof Parameterized *p) {} // CHECK-LABEL: define void @_Z19parameterized_test3P13Parameterized void parameterized_test3(Parameterized *p) {} + +// CHECK-LABEL: define {{.*}}void @_Z1fP11objc_object +void f(__attribute__((ns_consumed)) id) {} +// CHECK-LABEL: define {{.*}}void @_Z1fPFP11objc_objectS0_S0_E +void f(id (*fn)(__attribute__((ns_consumed)) id, id)) {} +// CHECK-LABEL: define {{.*}}void @_Z1fU13block_pointerFvP11objc_objectE +void f(void (^)(__attribute__((ns_consumed)) id)) {}