diff --git a/include/mull/JunkDetection/CXX/ASTStorage.h b/include/mull/JunkDetection/CXX/ASTStorage.h index cc7a8acdf..16447c53a 100644 --- a/include/mull/JunkDetection/CXX/ASTStorage.h +++ b/include/mull/JunkDetection/CXX/ASTStorage.h @@ -28,6 +28,7 @@ class ThreadSafeASTUnit { bool isInSystemHeader(clang::SourceLocation &location); clang::Decl *getDecl(clang::SourceLocation &location); + bool hasAST() const; private: void recordDeclarations(); diff --git a/lib/Driver.cpp b/lib/Driver.cpp index 75b5a8b89..27cfb93aa 100644 --- a/lib/Driver.cpp +++ b/lib/Driver.cpp @@ -397,6 +397,7 @@ void mull::mutateBitcode(llvm::Module &module) { diagnostics.info("Using configuration "s + configPath); configuration = Configuration::loadFromDisk(diagnostics, configPath); } + configuration.parallelization.normalize(); if (configuration.debugEnabled) { diagnostics.enableDebugMode(); diff --git a/lib/JunkDetection/CXX/ASTStorage.cpp b/lib/JunkDetection/CXX/ASTStorage.cpp index 916766314..5d0f0c306 100644 --- a/lib/JunkDetection/CXX/ASTStorage.cpp +++ b/lib/JunkDetection/CXX/ASTStorage.cpp @@ -81,7 +81,9 @@ const clang::FileEntry *ThreadSafeASTUnit::findFileEntry(const std::string &file if (!llvm::sys::path::is_absolute(currentSourceFilePath)) { currentSourceFilePath = it->first->tryGetRealPathName(); } - if (currentSourceFilePath.equals(filePath)) { + llvm::SmallString realFilePath; + llvm::sys::fs::real_path(filePath, realFilePath); + if (currentSourceFilePath.equals(filePath) || currentSourceFilePath.equals(realFilePath)) { file = it->first; break; } @@ -181,6 +183,10 @@ clang::Decl *ThreadSafeASTUnit::getDecl(clang::SourceLocation &location) { return nullptr; } +bool ThreadSafeASTUnit::hasAST() const { + return ast != nullptr; +} + ASTStorage::ASTStorage(Diagnostics &diagnostics, const std::string &cxxCompilationDatabasePath, const std::string &cxxCompilationFlags, const std::unordered_map &bitcodeCompilationFlags) @@ -214,7 +220,9 @@ ThreadSafeASTUnit *ASTStorage::findAST(const std::string &sourceFile) { for (auto &flag : compilationFlags) { args.push_back(flag.c_str()); } - args.push_back(sourceFile.c_str()); + if (args.size() == 1) { + args.push_back(sourceFile.c_str()); + } clang::IntrusiveRefCntPtr diagnosticsEngine( clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions)); diff --git a/lib/JunkDetection/CXX/CXXJunkDetector.cpp b/lib/JunkDetection/CXX/CXXJunkDetector.cpp index 0ebded808..361478d6d 100755 --- a/lib/JunkDetection/CXX/CXXJunkDetector.cpp +++ b/lib/JunkDetection/CXX/CXXJunkDetector.cpp @@ -192,7 +192,7 @@ bool CXXJunkDetector::isJunk(MutationPoint *point) { } ThreadSafeASTUnit *ast = astStorage.findAST(point->getSourceLocation()); - if (!ast) { + if (!ast->hasAST()) { return true; } clang::SourceLocation location = ast->getLocation(point->getSourceLocation()); diff --git a/lib/JunkDetection/CXX/CompilationDatabase.cpp b/lib/JunkDetection/CXX/CompilationDatabase.cpp index 67bee6d15..9c54eaa48 100644 --- a/lib/JunkDetection/CXX/CompilationDatabase.cpp +++ b/lib/JunkDetection/CXX/CompilationDatabase.cpp @@ -39,12 +39,6 @@ static CompilationDatabase::Flags flagsFromCommand(const clang::tooling::Compile CompilationDatabase::Flags flags(command.CommandLine); flags = filterFlags(flags, true); - // The compilation database produced from running - // clang ... -MJ - // contains a file name in the "arguments" array. Since the file name - // itself is not a compilation flag we filter it out. - flags.erase(std::remove(flags.begin(), flags.end(), command.Filename), flags.end()); - // append extraFlags std::copy(std::begin(extraFlags), std::end(extraFlags), std::back_inserter(flags)); @@ -78,9 +72,6 @@ createBitcodeFlags(Diagnostics &diagnostics, fileFlags = filterFlags(fileFlags, true); - /// Remove file name from the list of flags - fileFlags.erase(std::remove(fileFlags.begin(), fileFlags.end(), filename), fileFlags.end()); - for (const auto &extraFlag : extraFlags) { fileFlags.push_back(extraFlag); } diff --git a/tests-lit/tests/junk_detection/02_junk_detection_using_extra_flags/mull.no_flag.yml b/tests-lit/tests/junk_detection/02_junk_detection_using_extra_flags/mull.no_flag.yml index f680e2dde..3c268d6a0 100644 --- a/tests-lit/tests/junk_detection/02_junk_detection_using_extra_flags/mull.no_flag.yml +++ b/tests-lit/tests/junk_detection/02_junk_detection_using_extra_flags/mull.no_flag.yml @@ -3,3 +3,4 @@ mutators: - cxx_remove_void_call compilerFlags: - -DWRONG_FLAG=1 + - ./sample.cpp diff --git a/tests-lit/tests/junk_detection/02_junk_detection_using_extra_flags/mull.with_flag.yml b/tests-lit/tests/junk_detection/02_junk_detection_using_extra_flags/mull.with_flag.yml index 6d5a9112e..47b71e5fe 100644 --- a/tests-lit/tests/junk_detection/02_junk_detection_using_extra_flags/mull.with_flag.yml +++ b/tests-lit/tests/junk_detection/02_junk_detection_using_extra_flags/mull.with_flag.yml @@ -3,3 +3,4 @@ mutators: - cxx_remove_void_call compilerFlags: - -DFLAG=1 + - ./sample.cpp diff --git a/tests-lit/tests/junk_detection/02_junk_detection_using_extra_flags/sample.cpp b/tests-lit/tests/junk_detection/02_junk_detection_using_extra_flags/sample.cpp index 1a38a8531..a71e2527f 100644 --- a/tests-lit/tests/junk_detection/02_junk_detection_using_extra_flags/sample.cpp +++ b/tests-lit/tests/junk_detection/02_junk_detection_using_extra_flags/sample.cpp @@ -21,8 +21,8 @@ RUN: %mull_cxx -linker=%clang_cxx -linker-flags="%sysroot" -disable-junk-detecti WITHOUT-JUNK-DETECTION:{{^.*}}sample.cpp:5:13: warning: Survived: Removed the call to the function [cxx_remove_void_call]{{$}} -RUN: cd / && env MULL_CONFIG=%S/mull.no_flag.yml %clang_cxx %sysroot -O0 %pass_mull_ir_frontend -g -DFLAG=1 %s -o %s-ir-no-flag.exe 2>&1 | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=WITH-JUNK-DETECTION-NO-FLAG-MUTATE -RUN: %mull_cxx -mutate-only -output=%s-no-flag.exe -linker=%clang_cxx -linker-flags="%sysroot" -mutators=cxx_add_to_sub -mutators=cxx_remove_void_call -reporters=IDE -ide-reporter-show-killed -compilation-flags '-DWRONG_FLAG=1' %s.exe 2>&1 | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=WITH-JUNK-DETECTION-NO-FLAG-MUTATE +RUN: cd %S && env MULL_CONFIG=%S/mull.no_flag.yml %clang_cxx %sysroot -O0 %pass_mull_ir_frontend -g -DFLAG=1 %s -o %s-ir-no-flag.exe 2>&1 | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=WITH-JUNK-DETECTION-NO-FLAG-MUTATE +RUN: %mull_cxx -mutate-only -output=%s-no-flag.exe -linker=%clang_cxx -linker-flags="%sysroot" -mutators=cxx_add_to_sub -mutators=cxx_remove_void_call -reporters=IDE -ide-reporter-show-killed -compilation-flags="-DWRONG_FLAG=1 %s" %s.exe 2>&1 | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=WITH-JUNK-DETECTION-NO-FLAG-MUTATE RUN: %mull_runner -ide-reporter-show-killed %s-no-flag.exe 2>&1 | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=WITH-JUNK-DETECTION-NO-FLAG RUN: %mull_runner -ide-reporter-show-killed %s-ir-no-flag.exe 2>&1 | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=WITH-JUNK-DETECTION-NO-FLAG @@ -35,8 +35,8 @@ WITH-JUNK-DETECTION-NO-FLAG-MUTATE:Make sure that the flags provided to Mull are TODO: It is interesting why there is no junk even if we have the error above. WITH-JUNK-DETECTION-NO-FLAG:[info] Killed mutants (1/1): -RUN: cd / && env MULL_CONFIG=%S/mull.with_flag.yml %clang_cxx %sysroot -O0 %pass_mull_ir_frontend -g -DFLAG=1 %s -o %s-ir-with-flag.exe 2>&1 | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=WITH-JUNK-DETECTION-WITH-FLAG-MUTATE -RUN: %mull_cxx -mutate-only -output=%s-with-flag.exe -linker=%clang_cxx -linker-flags="%sysroot" -mutators=cxx_add_to_sub -mutators=cxx_remove_void_call -reporters=IDE -ide-reporter-show-killed -compilation-flags '-DFLAG=1' %s.exe 2>&1 | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=WITH-JUNK-DETECTION-WITH-FLAG-MUTATE +RUN: cd %S && env MULL_CONFIG=%S/mull.with_flag.yml %clang_cxx %sysroot -O0 %pass_mull_ir_frontend -g -DFLAG=1 %s -o %s-ir-with-flag.exe 2>&1 | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=WITH-JUNK-DETECTION-WITH-FLAG-MUTATE +RUN: %mull_cxx -mutate-only -output=%s-with-flag.exe -linker=%clang_cxx -linker-flags="%sysroot" -mutators=cxx_add_to_sub -mutators=cxx_remove_void_call -reporters=IDE -ide-reporter-show-killed -compilation-flags '-DFLAG=1 %s' %s.exe 2>&1 | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=WITH-JUNK-DETECTION-WITH-FLAG-MUTATE RUN: %mull_runner -reporters=IDE -ide-reporter-show-killed %s-with-flag.exe 2>&1 | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=WITH-JUNK-DETECTION-WITH-FLAG RUN: %mull_runner -reporters=IDE -ide-reporter-show-killed %s-ir-with-flag.exe 2>&1 | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=WITH-JUNK-DETECTION-WITH-FLAG diff --git a/tests-lit/tests/runner/mutants-from-dylib/mull.yml b/tests-lit/tests/runner/mutants-from-dylib/mull.yml index 167ca63f0..335343c87 100644 --- a/tests-lit/tests/runner/mutants-from-dylib/mull.yml +++ b/tests-lit/tests/runner/mutants-from-dylib/mull.yml @@ -1,4 +1,5 @@ mutators: - cxx_add_to_sub compilerFlags: - - "-DSHARED_LIB" \ No newline at end of file + - "-DSHARED_LIB" + - ./test.c \ No newline at end of file diff --git a/tests-lit/tests/runner/mutants-from-dylib/test.c b/tests-lit/tests/runner/mutants-from-dylib/test.c index eb656f259..e38e8f605 100644 --- a/tests-lit/tests/runner/mutants-from-dylib/test.c +++ b/tests-lit/tests/runner/mutants-from-dylib/test.c @@ -24,7 +24,7 @@ RUN: %clang_cc %sysroot -DSHARED_LIB -fPIC -shared %s %pass_mull_ir_frontend -g RUN: cd %S; %clang_cc %sysroot -DTEST_BIN ./test.c %S/shared-ir.lib -o ./test-ir.exe RUN: %clang_cc %sysroot -DSHARED_LIB -fPIC -shared %s -fembed-bitcode -g -o %S/shared.lib -RUN: unset TERM; %mull_cxx -mutate-only --compilation-flags=-DSHARED_LIB -linker=%clang_cc -linker-flags="%sysroot -shared -fPIC" --output=%S/mutated.lib %S/shared.lib +RUN: unset TERM; %mull_cxx -mutate-only --compilation-flags="-DSHARED_LIB %s" -linker=%clang_cc -linker-flags="%sysroot -shared -fPIC" --output=%S/mutated.lib %S/shared.lib RUN: cd %S; %clang_cc %sysroot -DTEST_BIN ./test.c ./mutated.lib -o ./test.exe RUN: cd /; unset TERM; %mull_runner -ld-search-path=%S -ide-reporter-show-killed %S/test.exe | %filecheck %s --dump-input=fail --match-full-lines --check-prefix=CHECK RUN: cd /; unset TERM; %mull_runner -ld-search-path=%S -ide-reporter-show-killed %S/test-ir.exe | %filecheck %s --dump-input=fail --match-full-lines --check-prefix=CHECK diff --git a/tools/mull-cxx-ir-frontend/CMakeLists.txt b/tools/mull-cxx-ir-frontend/CMakeLists.txt index 8ef36aa2d..c4dfaa3b4 100644 --- a/tools/mull-cxx-ir-frontend/CMakeLists.txt +++ b/tools/mull-cxx-ir-frontend/CMakeLists.txt @@ -5,4 +5,7 @@ target_include_directories(mull-cxx-ir-frontend-${LLVM_VERSION_MAJOR} SYSTEM PRI set_target_properties(mull-cxx-ir-frontend-${LLVM_VERSION_MAJOR} PROPERTIES COMPILE_FLAGS ${MULL_CXX_FLAGS}) set_target_properties(mull-cxx-ir-frontend-${LLVM_VERSION_MAJOR} PROPERTIES LIBRARY_OUTPUT_NAME mull-ir-frontend-${LLVM_VERSION_MAJOR}) set_target_properties(mull-cxx-ir-frontend-${LLVM_VERSION_MAJOR} PROPERTIES PREFIX "") -set_target_properties(mull-cxx-ir-frontend-${LLVM_VERSION_MAJOR} PROPERTIES SUFFIX "") \ No newline at end of file +set_target_properties(mull-cxx-ir-frontend-${LLVM_VERSION_MAJOR} PROPERTIES SUFFIX "") +install(TARGETS mull-cxx-ir-frontend-${LLVM_VERSION_MAJOR} + RUNTIME DESTINATION lib +) \ No newline at end of file diff --git a/tools/mull-cxx-ir-frontend/mull-cxx-ir-frontend.cpp b/tools/mull-cxx-ir-frontend/mull-cxx-ir-frontend.cpp index 9a19c6ba4..dc46c6eee 100644 --- a/tools/mull-cxx-ir-frontend/mull-cxx-ir-frontend.cpp +++ b/tools/mull-cxx-ir-frontend/mull-cxx-ir-frontend.cpp @@ -9,8 +9,9 @@ namespace { class MullIRFrontend : public llvm::PassInfoMixin { public: llvm::PreservedAnalyses run(llvm::Module &module, llvm::ModuleAnalysisManager &mam) { + // module.print(llvm::errs(), nullptr); mull::mutateBitcode(module); - module.print(llvm::errs(), nullptr); + // module.print(llvm::errs(), nullptr); return llvm::PreservedAnalyses::none(); } };