From 14b352ee16d47ecd4636004cefbced6f4f3ec6a8 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 3 Oct 2019 23:42:44 +0000 Subject: [PATCH] LowerTypeTests: Rename local functions to avoid collisions with identically named functions in ThinLTO modules. Without this we can encounter link errors or incorrect behaviour at runtime as a result of the wrong function being referenced. Differential Revision: https://reviews.llvm.org/D67945 llvm-svn: 373678 --- lib/Transforms/IPO/LowerTypeTests.cpp | 11 +++++++++++ .../LowerTypeTests/export-rename-local.ll | 15 +++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 test/Transforms/LowerTypeTests/export-rename-local.ll diff --git a/lib/Transforms/IPO/LowerTypeTests.cpp b/lib/Transforms/IPO/LowerTypeTests.cpp index 1b83ccb816e..36562961744 100644 --- a/lib/Transforms/IPO/LowerTypeTests.cpp +++ b/lib/Transforms/IPO/LowerTypeTests.cpp @@ -1887,6 +1887,17 @@ bool LowerTypeTestsModule::lower() { CfiFunctionLinkage Linkage = P.second.Linkage; MDNode *FuncMD = P.second.FuncMD; Function *F = M.getFunction(FunctionName); + if (F && F->hasLocalLinkage()) { + // Locally defined function that happens to have the same name as a + // function defined in a ThinLTO module. Rename it to move it out of + // the way of the external reference that we're about to create. + // Note that setName will find a unique name for the function, so even + // if there is an existing function with the suffix there won't be a + // name collision. + F->setName(F->getName() + ".1"); + F = nullptr; + } + if (!F) F = Function::Create( FunctionType::get(Type::getVoidTy(M.getContext()), false), diff --git a/test/Transforms/LowerTypeTests/export-rename-local.ll b/test/Transforms/LowerTypeTests/export-rename-local.ll new file mode 100644 index 00000000000..9e7c54ee94a --- /dev/null +++ b/test/Transforms/LowerTypeTests/export-rename-local.ll @@ -0,0 +1,15 @@ +; RUN: opt -S %s -lowertypetests -lowertypetests-summary-action=export -lowertypetests-read-summary=%S/Inputs/exported-funcs.yaml | FileCheck %s + +; CHECK: define internal void @external_addrtaken.1() +; CHECK: declare {{.*}} void @external_addrtaken.cfi() + +target triple = "x86_64-unknown-linux" + +define internal void @external_addrtaken() !type !1 { + ret void +} + +!cfi.functions = !{!0} + +!0 = !{!"external_addrtaken", i8 0, !1} +!1 = !{i64 0, !"typeid1"}