diff --git a/gen/toir.cpp b/gen/toir.cpp index 4ca39d2e..08f5c0c5 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -11,6 +11,7 @@ #include #include "gen/llvm.h" +#include "llvm/Support/CommandLine.h" #include "attrib.h" #include "init.h" @@ -38,9 +39,14 @@ #include "gen/todebug.h" #include "gen/nested.h" #include "gen/utils.h" +#include "gen/warnings.h" #include "llvm/Support/ManagedStatic.h" +llvm::cl::opt checkPrintf("check-printf-calls", + llvm::cl::desc("Validate printf call format strings against arguments"), + llvm::cl::ZeroOrMore); + ////////////////////////////////////////////////////////////////////////////////////////// void Expression::cacheLvalue(IRState* irs) @@ -784,6 +790,16 @@ DValue* CallExp::toElem(IRState* p) if (dfnval && dfnval->func) { FuncDeclaration* fndecl = dfnval->func; + + // as requested by bearophile, see if it's a C printf call and that it's valid. + if (global.params.warnings && checkPrintf) + { + if (fndecl->linkage == LINKc && strcmp(fndecl->ident->string, "printf") == 0) + { + warnInvalidPrintfCall(loc, (Expression*)arguments->data[0], arguments->dim); + } + } + // va_start instruction if (fndecl->llvmInternal == LLVMva_start) { // llvm doesn't need the second param hence the override