Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -800,6 +800,14 @@ false); F->setAttributes(llvm::AttributeSet::get(getLLVMContext(), AttributeList)); F->setCallingConv(static_cast(CallingConv)); + + // If the optimization level is greater than 0 and we are compiling with ARC, + // we attach clang-arc-nodecrement string attribute to any decl with + // CFNoReleaseAttr attached. + if (CodeGenOpts.OptimizationLevel > 0 && + LangOpts.ObjCAutoRefCount&& D->hasAttr()) { + F->addFnAttr("clang-arc-norelease"); + } } /// Determines whether the language options require us to model Index: test/CodeGenObjC/arc-cf-no-release.m =================================================================== --- /dev/null +++ test/CodeGenObjC/arc-cf-no-release.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s + +// CHECK: define void @norelease_defn() #[[NORELEASE_DEFN_ATTR:[0-9]+]] { +// CHECK: define void @mayrelease_defn() #[[MAYRELEASE_DEFN_ATTR:[0-9]+]] { +// CHECK: declare void @norelease_decl(...) #[[NORELEASE_DECL_ATTR:[0-9]+]] +// CHECK: declare void @mayrelease_decl(...) #[[MAYRELEASE_DECL_ATTR:[0-9]+]] + +// CHECK: attributes #[[NORELEASE_DEFN_ATTR]] = { {{.*}}"clang-arc-norelease"{{.*}} } +// CHECK-NOT: attributes #[[MAYRELEASE_DEFN_ATTR]] = { {{.*}}"clang-arc-norelease"{{.*}} } +// CHECK: attributes #[[NORELEASE_DECL_ATTR]] = { {{.*}}"clang-arc-norelease"{{.*}}} +// CHECK-NOT: attributes [[MAYRELEASE_DEFN_ATTR]] = { {{.*}}"clang-arc-norelease"{{.*}} } + +void norelease_decl() __attribute__((cf_no_release)); +void mayrelease_decl(); + +void norelease_defn() __attribute__((cf_no_release)) {} +void mayrelease_defn() {} + +void call() { + norelease_decl(); + mayrelease_decl(); + norelease_defn(); + mayrelease_defn(); +}