diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 2611415bc..d52ab1629 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -197,6 +197,24 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) mSettings->verificationReport = argv[i] + 16; } else if (std::strcmp(argv[i], "--debug-verify") == 0) mSettings->debugVerification = true; + else if (std::strncmp(argv[i], "--verify-diff=", 14) == 0) { + std::ifstream fin(argv[i] + 14); + if (!fin.is_open()) { + printMessage("cppcheck: could not open file " + std::string(argv[i] + 14) + "."); + return false; + } + + mSettings->verifyDiff = Settings::loadDiffFile(fin); + mSettings->verification = true; + + for (const auto &diff: mSettings->verifyDiff) { + if (!Path::acceptFile(diff.filename)) + continue; + const std::string filename = Path::fromNativeSeparators(diff.filename); + if (std::find(mPathNames.begin(), mPathNames.end(), filename) == mPathNames.end()) + mPathNames.push_back(filename); + } + } // Enforce language (--language=, -x) else if (std::strncmp(argv[i], "--language=", 11) == 0 || std::strcmp(argv[i], "-x") == 0) { diff --git a/lib/exprengine.cpp b/lib/exprengine.cpp index ebd7c00c5..6f872f606 100644 --- a/lib/exprengine.cpp +++ b/lib/exprengine.cpp @@ -1694,6 +1694,23 @@ void ExprEngine::executeFunction(const Scope *functionScope, const Tokenizer *to // TODO.. what about functions in headers? return; + if (!settings->verifyDiff.empty()) { + const std::string filename = tokenizer->list.getFiles().at(functionScope->bodyStart->fileIndex()); + bool verify = false; + for (const auto &diff: settings->verifyDiff) { + if (diff.filename != filename) + continue; + if (diff.fromLine > functionScope->bodyEnd->linenr()) + continue; + if (diff.toLine < functionScope->bodyStart->linenr()) + continue; + verify = true; + break; + } + if (!verify) + return; + } + int symbolValueIndex = 0; TrackExecution trackExecution; Data data(&symbolValueIndex, tokenizer, settings, callbacks, &trackExecution); diff --git a/lib/settings.cpp b/lib/settings.cpp index f291dd923..f329bc552 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -149,3 +149,39 @@ bool Settings::isEnabled(const ValueFlow::Value *value, bool inconclusiveCheck) return false; return true; } + +std::vector Settings::loadDiffFile(std::istream &istr) +{ + std::vector ret; + std::string line; + std::string filename; + while (std::getline(istr, line)) { + if (line.compare(0, 11, "diff --git ") == 0) { + std::string::size_type pos = line.rfind(" b/"); + if (pos == std::string::npos) + continue; + filename = line.substr(pos+3); + } + if (line.compare(0,4,"@@ -") == 0) { + std::string::size_type pos1 = line.find(" ",4); + if (pos1 == std::string::npos) + continue; + std::string::size_type pos2 = line.find(" ",pos1 + 1); + if (pos2 == std::string::npos || pos2 < pos1+3) + continue; + if (line[pos1+1] != '+') + continue; + std::string::size_type posComma = line.find(",", pos1); + if (posComma > pos2) + continue; + std::string line1 = line.substr(pos1 + 2, posComma - pos1 - 2); + std::string line2 = line.substr(posComma+1, pos2 - posComma - 1); + Diff diff; + diff.filename = filename; + diff.fromLine = std::atoi(line1.c_str()); + diff.toLine = std::atoi(line1.c_str()) + std::atoi(line2.c_str()); + ret.push_back(diff); + } + } + return ret; +} diff --git a/lib/settings.h b/lib/settings.h index 675125788..2caacfaf1 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -197,6 +197,14 @@ public: /** @brief Generate verification debug output */ bool debugVerification; + /** @brief Verify diff */ + struct Diff { + std::string filename; + int fromLine; + int toLine; + }; + std::vector verifyDiff; + /** @brief check unknown function return values */ std::set checkUnknownFunctionReturn; @@ -360,6 +368,8 @@ public: */ bool isEnabled(const ValueFlow::Value *value, bool inconclusiveCheck=false) const; + static std::vector loadDiffFile(std::istream &istr); + /** Is posix library specified? */ bool posix() const { return std::find(libraries.begin(), libraries.end(), "posix") != libraries.end();