Index: llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -859,9 +859,17 @@ FunctionType *NewFT = getInstrumentedABI() == IA_Args ? getArgsFunctionType(FT) : FT; + + // If the function being wrapped has local linkage, then preserve the + // function's linkage in the wrapper function. + GlobalValue::LinkageTypes wrapperLinkage = + F.hasLocalLinkage() + ? F.getLinkage() + : GlobalValue::LinkOnceODRLinkage; + Function *NewF = buildWrapperFunction( &F, std::string("dfsw$") + std::string(F.getName()), - GlobalValue::LinkOnceODRLinkage, NewFT); + wrapperLinkage, NewFT); if (getInstrumentedABI() == IA_TLS) NewF->removeAttributes(AttributeList::FunctionIndex, ReadOnlyNoneAttrs); Index: llvm/trunk/test/Instrumentation/DataFlowSanitizer/Inputs/abilist.txt =================================================================== --- llvm/trunk/test/Instrumentation/DataFlowSanitizer/Inputs/abilist.txt +++ llvm/trunk/test/Instrumentation/DataFlowSanitizer/Inputs/abilist.txt @@ -6,3 +6,5 @@ fun:custom*=uninstrumented fun:custom*=custom + +fun:uninstrumented*=uninstrumented Index: llvm/trunk/test/Instrumentation/DataFlowSanitizer/uninstrumented_local_functions.ll =================================================================== --- llvm/trunk/test/Instrumentation/DataFlowSanitizer/uninstrumented_local_functions.ll +++ llvm/trunk/test/Instrumentation/DataFlowSanitizer/uninstrumented_local_functions.ll @@ -0,0 +1,24 @@ +; RUN: opt < %s -dfsan -dfsan-args-abi -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s +; RUN: opt < %s -dfsan -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" + +define internal i8 @uninstrumented_internal_fun(i8 %in) { + ret i8 %in +} + +define i8 @call_uninstrumented_internal_fun(i8 %in) { + %call = call i8 @uninstrumented_internal_fun(i8 %in) + ret i8 %call +} +; CHECK: define internal {{(i8|{ i8, i16 })}} @"dfsw$uninstrumented_internal_fun" + +define private i8 @uninstrumented_private_fun(i8 %in) { + ret i8 %in +} + +define i8 @call_uninstrumented_private_fun(i8 %in) { + %call = call i8 @uninstrumented_private_fun(i8 %in) + ret i8 %call +} +; CHECK: define private {{(i8|{ i8, i16 })}} @"dfsw$uninstrumented_private_fun"