Index: lib/Transforms/Instrumentation/DataFlowSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -1531,7 +1531,33 @@ CallInst *CustomCI = IRB.CreateCall(CustomF, Args); CustomCI->setCallingConv(CI->getCallingConv()); - CustomCI->setAttributes(CI->getAttributes()); + + if (FT->isVarArg()) { + AttributeList OldAttrs = CI->getAttributes(); + SmallVector ArgAttrs; + const unsigned NonVarArgCount = FT->getNumParams(); + const unsigned ShadowArgCount = + CustomFT->getNumParams() - NonVarArgCount; + + // Copy non-vararg attributes. + for (unsigned n = 0; n < NonVarArgCount; n++) { + ArgAttrs.push_back(OldAttrs.getParamAttributes(n)); + } + // Skip label parameters. + for (unsigned n = 0; n < ShadowArgCount; n++) { + ArgAttrs.push_back(AttributeSet()); + } + // Copy vararg attributes. + for (unsigned n = NonVarArgCount; n < CS.arg_size(); n++) { + ArgAttrs.push_back(OldAttrs.getParamAttributes(n)); + } + + CustomCI->setAttributes(AttributeList::get( + F->getContext(), OldAttrs.getFnAttributes(), + OldAttrs.getRetAttributes(), ArgAttrs)); + } else { + CustomCI->setAttributes(CI->getAttributes()); + } // Update the parameter attributes of the custom call instruction to // zero extend the shadow parameters. This is required for targets Index: test/Instrumentation/DataFlowSanitizer/Inputs/sprintf-abilist.txt =================================================================== --- test/Instrumentation/DataFlowSanitizer/Inputs/sprintf-abilist.txt +++ test/Instrumentation/DataFlowSanitizer/Inputs/sprintf-abilist.txt @@ -0,0 +1,2 @@ +fun:sprintf=custom +fun:sprintf=uninstrumented Index: test/Instrumentation/DataFlowSanitizer/custom-attrs.ll =================================================================== --- test/Instrumentation/DataFlowSanitizer/custom-attrs.ll +++ test/Instrumentation/DataFlowSanitizer/custom-attrs.ll @@ -0,0 +1,16 @@ +; RUN: opt < %s -dfsan -dfsan-args-abi -dfsan-abilist=%S/Inputs/sprintf-abilist.txt -S | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @f() { + ; CHECK: call signext i32 {{.*}} @__dfsw_sprintf(i8* align 1 undef, i8* align 2 undef, i16 zeroext 0, i16 zeroext 0, i16* %{{.*}}, i16* %{{.*}}) #[[ATTR:[0-9]+]] + ; CHECK: call signext i32 {{.*}} @__dfsw_sprintf(i8* align 1 undef, i8* align 2 undef, i16 zeroext 0, i16 zeroext 0, i16* %{{.*}}, i16* %{{.*}}, i8* align 4 undef, i8* align 8 undef) #[[ATTR:[0-9]+]] + ; attributes #[[ATTR]] = { nounwind } + call signext i32 (i8*, i8*, ...) @sprintf(i8* align 1 undef, i8* align 2 undef) #1 + call signext i32 (i8*, i8*, ...) @sprintf(i8* align 1 undef, i8* align 2 undef, i8* align 4 undef, i8* align 8 undef) #1 + ret void +} + +declare i32 @sprintf(i8*, i8*, ...) +attributes #1 = { nounwind }