diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp --- a/llvm/lib/Linker/LinkModules.cpp +++ b/llvm/lib/Linker/LinkModules.cpp @@ -375,8 +375,15 @@ GV.hasAvailableExternallyLinkage())) return false; - if (GV.isDeclaration()) + // Since nocallback function attribute is treated as a hint on + // the module level, it is removed while linking modules. + if (GV.isDeclaration()) { + if (auto *F = dyn_cast(&GV)) + if (F->hasFnAttribute(llvm::Attribute::NoCallback)) + F->removeFnAttr(llvm::Attribute::NoCallback); + return false; + } LinkFrom ComdatFrom = LinkFrom::Dst; if (const Comdat *SC = GV.getComdat()) { diff --git a/llvm/test/Linker/Inputs/drop-attribute.ll b/llvm/test/Linker/Inputs/drop-attribute.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Linker/Inputs/drop-attribute.ll @@ -0,0 +1,4 @@ +define void @bar() { +entry: + ret void +} diff --git a/llvm/test/Linker/drop-attribute.ll b/llvm/test/Linker/drop-attribute.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Linker/drop-attribute.ll @@ -0,0 +1,17 @@ +; RUN: llvm-link %s %p/Inputs/drop-attribute.ll -S -o - | FileCheck %s + +; Test case that checks that nocallback attribute is dropped during linking. + +; CHECK: define i32 @main() +define i32 @main() { +entry: + call void @test_nocallback() + ret i32 0 +} + +; CHECK-NOT: Function Attrs: +; CHECK: declare void @test_nocallback() +declare void @test_nocallback() nocallback + +; CHECK-NOT: attributes #0 = { } +