diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2019-11-15 15:27:56 -0800 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2019-11-15 15:44:04 -0800 |
commit | 4516dc1c20d1e77f20a72e90be876506805b3978 (patch) | |
tree | 85f5cce6ea11bb42499c6ac0ef782e165199583e | |
parent | a578adc1bc8e17b147ed5ef4794cd6f3f82b584b (diff) | |
download | bcm5719-llvm-4516dc1c20d1e77f20a72e90be876506805b3978.tar.gz bcm5719-llvm-4516dc1c20d1e77f20a72e90be876506805b3978.zip |
Don't add optnone or noinline if the function is already marked as
always_inline.
The assertion in SetLLVMFunctionAttributesForDefinition used to fail
when there was attribute OptimizeNone on the AST function and attribute
always_inline on the IR function. This happens because base destructors
are annotated with always_inline when the code is compiled with
-fapple-kext (see r124757).
rdar://problem/57169694
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 10 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/apple-kext.cpp | 22 |
2 files changed, 27 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index b7db1f49c0e..e253bbc1991 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1515,16 +1515,15 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, !CodeGenOpts.DisableO0ImplyOptNone && CodeGenOpts.OptimizationLevel == 0; // We can't add optnone in the following cases, it won't pass the verifier. ShouldAddOptNone &= !D->hasAttr<MinSizeAttr>(); - ShouldAddOptNone &= !F->hasFnAttribute(llvm::Attribute::AlwaysInline); ShouldAddOptNone &= !D->hasAttr<AlwaysInlineAttr>(); - if (ShouldAddOptNone || D->hasAttr<OptimizeNoneAttr>()) { + // Add optnone, but do so only if the function isn't always_inline. + if ((ShouldAddOptNone || D->hasAttr<OptimizeNoneAttr>()) && + !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) { B.addAttribute(llvm::Attribute::OptimizeNone); // OptimizeNone implies noinline; we should not be inlining such functions. B.addAttribute(llvm::Attribute::NoInline); - assert(!F->hasFnAttribute(llvm::Attribute::AlwaysInline) && - "OptimizeNone and AlwaysInline on same function!"); // We still need to handle naked functions even though optnone subsumes // much of their semantics. @@ -1540,7 +1539,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, B.addAttribute(llvm::Attribute::NoInline); } else if (D->hasAttr<NoDuplicateAttr>()) { B.addAttribute(llvm::Attribute::NoDuplicate); - } else if (D->hasAttr<NoInlineAttr>()) { + } else if (D->hasAttr<NoInlineAttr>() && !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) { + // Add noinline if the function isn't always_inline. B.addAttribute(llvm::Attribute::NoInline); } else if (D->hasAttr<AlwaysInlineAttr>() && !F->hasFnAttribute(llvm::Attribute::NoInline)) { diff --git a/clang/test/CodeGenCXX/apple-kext.cpp b/clang/test/CodeGenCXX/apple-kext.cpp index 0d7ccfb3be1..990bc146c57 100644 --- a/clang/test/CodeGenCXX/apple-kext.cpp +++ b/clang/test/CodeGenCXX/apple-kext.cpp @@ -4,6 +4,25 @@ // CHECK: @llvm.global_ctors = appending global {{.*}} { i32 65535, void ()* [[CTOR0:@.*]], i8* null } // CHECK: @llvm.global_dtors = appending global {{.*}} { i32 65535, void ()* [[DTOR0:@.*]], i8* null } +// Check that the base destructor is marked as always_inline when generating +// code for kext. + +namespace testBaseDestructor { +#pragma clang optimize off +struct D { + virtual ~D(); +}; + +D::~D() {} +#pragma clang optimize on +} + +// CHECK: define void @_ZN18testBaseDestructor1DD2Ev({{.*}}) unnamed_addr #[[ATTR0:.*]] align 2 { + +// CHECK: define void @_ZN18testBaseDestructor1DD1Ev({{.*}}) unnamed_addr #[[ATTR1:.*]] align 2 { + +// CHECK: define void @_ZN18testBaseDestructor1DD0Ev({{.*}}) unnamed_addr #[[ATTR1]] align 2 { + // rdar://11241230 namespace test0 { struct A { A(); ~A(); }; @@ -20,3 +39,6 @@ namespace test0 { // CHECK: define internal void [[DTOR0]]() // CHECK: call void @_ZN5test01AD1Ev([[A]]* @_ZN5test01aE) // CHECK-NEXT: ret void + +// CHECK: attributes #[[ATTR0]] = { alwaysinline nounwind {{.*}} } +// CHECK: attributes #[[ATTR1]] = { noinline nounwind {{.*}} } |