Index: llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -387,7 +387,12 @@ } FunctionType *DataFlowSanitizer::getCustomFunctionType(FunctionType *T) { - assert(!T->isVarArg()); + if (T->isVarArg()) { + // The labels are passed after all the arguments so there is no need to + // adjust the function type. + return T; + } + llvm::SmallVector ArgTypes; for (FunctionType::param_iterator i = T->param_begin(), e = T->param_end(); i != e; ++i) { @@ -476,7 +481,7 @@ return WK_Functional; if (ABIList.isIn(*F, "discard")) return WK_Discard; - if (ABIList.isIn(*F, "custom") && !F->isVarArg()) + if (ABIList.isIn(*F, "custom")) return WK_Custom; return WK_Warning; @@ -704,11 +709,6 @@ } else { addGlobalNamePrefix(&F); } - // Hopefully, nobody will try to indirectly call a vararg - // function... yet. - } else if (FT->isVarArg()) { - UnwrappedFnMap[&F] = &F; - *i = nullptr; } else if (!IsZeroArgsVoidRet || getWrapperKind(&F) == WK_Custom) { // Build a wrapper function for F. The wrapper simply calls F, and is // added to FnsToInstrument so that any instrumentation according to its @@ -744,6 +744,11 @@ i = FnsToInstrument.begin() + N; e = FnsToInstrument.begin() + Count; } + // Hopefully, nobody will try to indirectly call a vararg + // function... yet. + } else if (FT->isVarArg()) { + UnwrappedFnMap[&F] = &F; + *i = nullptr; } } @@ -1352,6 +1357,10 @@ return; } + assert(!(cast( + CS.getCalledValue()->getType()->getPointerElementType())->isVarArg() && + dyn_cast(CS.getInstruction()))); + IRBuilder<> IRB(CS.getInstruction()); DenseMap::iterator i = @@ -1400,7 +1409,7 @@ std::vector Args; CallSite::arg_iterator i = CS.arg_begin(); - for (unsigned n = FT->getNumParams(); n != 0; ++i, --n) { + for (unsigned n = CS.arg_size(); n != 0; ++i, --n) { Type *T = (*i)->getType(); FunctionType *ParamFT; if (isa(T) && @@ -1420,7 +1429,7 @@ } i = CS.arg_begin(); - for (unsigned n = FT->getNumParams(); n != 0; ++i, --n) + for (unsigned n = CS.arg_size(); n != 0; ++i, --n) Args.push_back(DFSF.getShadow(*i)); if (!FT->getReturnType()->isVoidTy()) { Index: llvm/trunk/test/Instrumentation/DataFlowSanitizer/abilist.ll =================================================================== --- llvm/trunk/test/Instrumentation/DataFlowSanitizer/abilist.ll +++ llvm/trunk/test/Instrumentation/DataFlowSanitizer/abilist.ll @@ -16,7 +16,9 @@ declare i32 @custom2(i32 %a, i32 %b) -declare void @custom3(...) +declare void @custom3(i32 %a, ...) + +declare i32 @custom4(i32 %a, ...) declare void @customcb(i32 (i32)* %cb) @@ -35,9 +37,11 @@ ; CHECK: call void @__dfsw_customcb({{.*}} @"dfst0$customcb", i8* bitcast ({{.*}} @"dfs$cb" to i8*), i16 0) call void @customcb(i32 (i32)* @cb) - ; CHECK: call void @__dfsan_unimplemented - ; CHECK: call void (...)* @custom3() - call void (...)* @custom3() + ; CHECK: call void (i32, ...)* @__dfsw_custom3(i32 1, i32 2, i32 3, i16 0, i16 0, i16 0) + call void (i32, ...)* @custom3(i32 1, i32 2, i32 3) + + ; CHECK: call i32 (i32, ...)* @__dfsw_custom4(i32 1, i32 2, i32 3, i16 0, i16 0, i16 0, i16* %[[LABELRETURN]]) + call i32 (i32, ...)* @custom4(i32 1, i32 2, i32 3) ret void } @@ -71,6 +75,8 @@ ; CHECK: declare void @__dfsw_custom1(i32, i32, i16, i16) ; CHECK: declare i32 @__dfsw_custom2(i32, i32, i16, i16, i16*) +; CHECK: declare void @__dfsw_custom3(i32, ...) +; CHECK: declare i32 @__dfsw_custom4(i32, ...) ; CHECK-LABEL: define linkonce_odr i32 @"dfst0$customcb"(i32 (i32)*, i32, i16, i16*) ; CHECK: %[[BC:.*]] = bitcast i32 (i32)* %0 to { i32, i16 } (i32, i16)*