From f9a2e90b2b5e7fc8325c20213ba5096547785ab9 Mon Sep 17 00:00:00 2001 From: Vladislav Kalugin Date: Sun, 10 Dec 2023 00:29:48 +0300 Subject: [PATCH] Add skip duplicate compile commands (#660) --- server/src/KleeGenerator.cpp | 31 ++++++++++--------- server/src/building/ProjectBuildDatabse.cpp | 13 +++++++- .../GlobalVariableUsageMatchCallback.cpp | 12 +++---- server/src/printers/Printer.h | 2 +- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/server/src/KleeGenerator.cpp b/server/src/KleeGenerator.cpp index de703e555..d206a2c87 100644 --- a/server/src/KleeGenerator.cpp +++ b/server/src/KleeGenerator.cpp @@ -153,8 +153,10 @@ KleeGenerator::getCompileCommandForKlee(const fs::path &hintPath, } command.setSourcePath(srcFilePath); - auto outFilePath = (forStub ? testGen->getProjectBuildDatabase()->getBitcodeFile(compilationUnitInfo->getOutputFile()) - : testGen->getTargetBuildDatabase()->getBitcodeFile(compilationUnitInfo->getOutputFile())); + auto outFilePath = (forStub ? testGen->getProjectBuildDatabase()->getBitcodeFile( + compilationUnitInfo->getOutputFile()) + : testGen->getTargetBuildDatabase()->getBitcodeFile( + compilationUnitInfo->getOutputFile())); fs::create_directories(outFilePath.parent_path()); command.setOutput(outFilePath); command.setOptimizationLevel("-O0"); @@ -227,7 +229,7 @@ Result KleeGenerator::defaultBuild(const fs::path &hintPath, auto makefileCommand = MakefileUtils::MakefileCommand(testGen->projectContext, makefile, printer::DefaultMakefilePrinter::TARGET_BUILD); - auto[out, status, _] = makefileCommand.run(); + auto [out, status, _] = makefileCommand.run(); if (status != 0) { LOG_S(ERROR) << "Compilation for " << sourceFilePath << " failed.\n" << "Command: \"" << commandWithChangingDirectory.toString() << "\"\n" @@ -264,7 +266,8 @@ std::vector KleeGenerator::buildKleeFiles(const tests::TestsMap &tests const std::shared_ptr &lineInfo) { std::vector outFiles; LOG_S(DEBUG) << "Building generated klee files..."; - printer::KleePrinter kleePrinter(&typesHandler, testGen->getTargetBuildDatabase(), utbot::Language::UNKNOWN, testGen); + printer::KleePrinter kleePrinter(&typesHandler, testGen->getTargetBuildDatabase(), utbot::Language::UNKNOWN, + testGen); ExecUtils::doWorkWithProgress( testsMap, testGen->progressWriter, "Building generated klee files", [&](auto const &it) { @@ -344,14 +347,14 @@ std::vector KleeGenerator::buildKleeFiles(const tests::TestsMap &tests } void KleeGenerator::parseKTestsToFinalCode( - const utbot::ProjectContext &projectContext, - tests::Tests &tests, - const std::unordered_map &methodNameToReturnTypeMap, - const std::vector &kleeOutput, - const std::shared_ptr &lineInfo, - bool verbose, - ErrorMode errorMode) { - for (const auto &batch : kleeOutput) { + const utbot::ProjectContext &projectContext, + tests::Tests &tests, + const std::unordered_map &methodNameToReturnTypeMap, + const std::vector &kleeOutput, + const std::shared_ptr &lineInfo, + bool verbose, + ErrorMode errorMode) { + for (const auto &batch: kleeOutput) { bool filterByFlag = (lineInfo != nullptr && !lineInfo->forMethod && !lineInfo->forClass && !lineInfo->predicateInfo.has_value()); tests::KTestObjectParser KTestObjectParser(typesHandler); @@ -375,12 +378,12 @@ void KleeGenerator::parseKTestsToFinalCode( continue; } auto predicate = - lineInfo ? lineInfo->predicateInfo : std::optional{}; + lineInfo ? lineInfo->predicateInfo : std::optional{}; testsPrinter.genCode(methodDescription, predicate, verbose, errorMode); } printer::HeaderPrinter(Paths::getSourceLanguage(tests.sourceFilePath)) - .print(tests.testHeaderFilePath, tests.sourceFilePath, tests.headerCode); + .print(tests.testHeaderFilePath, tests.sourceFilePath, tests.headerCode); testsPrinter.joinToFinalCode(tests, tests.testHeaderFilePath); LOG_S(DEBUG) << "Generated code for " << tests.methods.size() << " tests"; } diff --git a/server/src/building/ProjectBuildDatabse.cpp b/server/src/building/ProjectBuildDatabse.cpp index 39d711f32..cddbb5254 100644 --- a/server/src/building/ProjectBuildDatabse.cpp +++ b/server/src/building/ProjectBuildDatabse.cpp @@ -103,12 +103,23 @@ void ProjectBuildDatabase::initObjects(const nlohmann::json &compileCommandsJson LOG_S(WARNING) << "Source file " << sourceFile << " outside of project root " << projectContext.projectPath; kleeFilePathTemplate = Paths::createNewDirForFile(sourceFile, fs::path("/"), - Paths::getUTBotFiles(projectContext) / "outside_of_project"); + Paths::getUTBotFiles(projectContext) / + "outside_of_project"); } fs::path kleeFile = Paths::addSuffix(kleeFilePathTemplate, "_klee"); objectInfo->kleeFilesInfo = std::make_shared(kleeFile); + if (CollectionUtils::containsKey(objectFileInfos, outputFile) && Paths::isObjectFile(outputFile)) { + auto previusInfo = objectFileInfos[outputFile]; + if (previusInfo->command.getCommandLine() == objectInfo->command.getCommandLine()) { + LOG_S(WARNING) << "Skip duplicate compile command for object file: " << outputFile; + } else { + LOG_S(WARNING) << "Skip second compile command for object file: " << outputFile; + } + continue; + } + if (CollectionUtils::containsKey(objectFileInfos, outputFile) || CollectionUtils::containsKey(targetInfos, outputFile)) { /* diff --git a/server/src/fetchers/GlobalVariableUsageMatchCallback.cpp b/server/src/fetchers/GlobalVariableUsageMatchCallback.cpp index faf6bbfb0..34053b6c6 100644 --- a/server/src/fetchers/GlobalVariableUsageMatchCallback.cpp +++ b/server/src/fetchers/GlobalVariableUsageMatchCallback.cpp @@ -13,7 +13,7 @@ void GlobalVariableUsageMatchCallback::run(const MatchFinder::MatchResult &Resul checkUsage(Result); } -static std::unordered_set BLACK_LIST = { "stdin", "stdout", "stderr" }; +static std::unordered_set BLACK_LIST = {"stdin", "stdout", "stderr"}; void GlobalVariableUsageMatchCallback::checkUsage(const MatchFinder::MatchResult &Result) { if (const auto *pVarDecl = @@ -50,7 +50,7 @@ void GlobalVariableUsageMatchCallback::handleUsage(const clang::FunctionDecl *fu clang::SourceManager &sourceManager = functionDecl->getASTContext().getSourceManager(); fs::path sourceFilePath = ClangUtils::getSourceFilePath(sourceManager); auto const &[iterator, inserted] = - usages.emplace(varDecl->getNameAsString(), functionDecl->getNameAsString()); + usages.emplace(varDecl->getNameAsString(), functionDecl->getNameAsString()); auto const &usage = *iterator; LOG_S(MAX) << "Found usage of global variable \'" << usage.variableName << "\' in function \'" @@ -73,21 +73,21 @@ void GlobalVariableUsageMatchCallback::handleUsage(const clang::FunctionDecl *fu } GlobalVariableUsageMatchCallback::Usage::Usage(std::string variableName, std::string functionName) - : variableName(std::move(variableName)), functionName(std::move(functionName)) { + : variableName(std::move(variableName)), functionName(std::move(functionName)) { } bool GlobalVariableUsageMatchCallback::Usage::operator==( - const GlobalVariableUsageMatchCallback::Usage &rhs) const { + const GlobalVariableUsageMatchCallback::Usage &rhs) const { return variableName == rhs.variableName && functionName == rhs.functionName; } bool GlobalVariableUsageMatchCallback::Usage::operator!=( - const GlobalVariableUsageMatchCallback::Usage &rhs) const { + const GlobalVariableUsageMatchCallback::Usage &rhs) const { return !(rhs == *this); } std::size_t GlobalVariableUsageMatchCallback::UsageHash::operator()( - const GlobalVariableUsageMatchCallback::Usage &usage) const { + const GlobalVariableUsageMatchCallback::Usage &usage) const { size_t seed = 0; HashUtils::hashCombine(seed, usage.variableName, usage.functionName); return seed; diff --git a/server/src/printers/Printer.h b/server/src/printers/Printer.h index f0b6f8687..0520a7a79 100644 --- a/server/src/printers/Printer.h +++ b/server/src/printers/Printer.h @@ -29,7 +29,7 @@ namespace printer { typedef const std::vector &VSRef; typedef std::stringstream &Stream; - std::stringstream ss; + std::stringstream ss{}; int tabsDepth = 0; int commentDepth = 0; utbot::Language srcLanguage = utbot::Language::UNKNOWN;