Skip to content

Commit

Permalink
Fix junk detection: getting the filenames right is tricky
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexDenisov committed Jan 12, 2022
1 parent ff41302 commit 6217cf2
Show file tree
Hide file tree
Showing 15 changed files with 47 additions and 35 deletions.
1 change: 1 addition & 0 deletions include/mull/JunkDetection/CXX/ASTStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class ThreadSafeASTUnit {
bool isInSystemHeader(clang::SourceLocation &location);

clang::Decl *getDecl(clang::SourceLocation &location);
bool hasAST() const;

private:
void recordDeclarations();
Expand Down
1 change: 1 addition & 0 deletions lib/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
12 changes: 10 additions & 2 deletions lib/JunkDetection/CXX/ASTStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<PATH_MAX> realFilePath;
llvm::sys::fs::real_path(filePath, realFilePath);
if (currentSourceFilePath.equals(filePath) || currentSourceFilePath.equals(realFilePath)) {
file = it->first;
break;
}
Expand Down Expand Up @@ -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<std::string, std::string> &bitcodeCompilationFlags)
Expand Down Expand Up @@ -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<clang::DiagnosticsEngine> diagnosticsEngine(
clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions));
Expand Down
2 changes: 1 addition & 1 deletion lib/JunkDetection/CXX/CXXJunkDetector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
9 changes: 0 additions & 9 deletions lib/JunkDetection/CXX/CompilationDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <comp.database.json>
// 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));

Expand Down Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ mutators:
- cxx_remove_void_call
compilerFlags:
- -DWRONG_FLAG=1
- ./sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ mutators:
- cxx_remove_void_call
compilerFlags:
- -DFLAG=1
- ./sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion tests-lit/tests/runner/mutants-from-dylib/mull.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mutators:
- cxx_add_to_sub
compilerFlags:
- "-DSHARED_LIB"
- "-DSHARED_LIB"
- ./test.c
2 changes: 1 addition & 1 deletion tests-lit/tests/runner/mutants-from-dylib/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions tests/JunkDetection/CXXJunkDetectorTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,9 @@ TEST(CXXJunkDetector, no_compdb) {

ASSERT_EQ(points.size(), 8U);

std::string cxxCompilationFlags =
std::string("-I ") + fixtures::junk_detection_compdb_include__path();
std::string cxxCompilationFlags = std::string("-I ") +
fixtures::junk_detection_compdb_include__path() + " " +
bitcode->getModule()->getSourceFileName();

ASTStorage astStorage(diagnostics, "", cxxCompilationFlags, {});

Expand Down
27 changes: 15 additions & 12 deletions tests/JunkDetection/CompilationDatabaseTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,14 @@ TEST(CompilationDatabaseFromFile, loadsFromValidFiles) {
const CompilationDatabase database = CompilationDatabase::fromFile(diagnostics, path, "", {});

auto compilationFlags = database.compilationFlagsForFile(file);
ASSERT_EQ(compilationFlags.size(), size_t(5));
ASSERT_EQ(compilationFlags.size(), size_t(6));

ASSERT_EQ(compilationFlags.at(0), "-I"s);
ASSERT_EQ(compilationFlags.at(1), "foo"s);
ASSERT_EQ(compilationFlags.at(2), "-I"s);
ASSERT_EQ(compilationFlags.at(3), "bar"s);
ASSERT_EQ(compilationFlags.at(4), "-c"s);
ASSERT_EQ(compilationFlags.at(5), "foobar.cpp"s);
}
}
}
Expand All @@ -73,17 +74,18 @@ TEST(CompilationDatabaseFromFile, includesCompilationFlagsPassedSeparately) {

const std::string file("/foo/bar/foobar.cpp");
auto compilationFlags = database.compilationFlagsForFile(file);
ASSERT_EQ(compilationFlags.size(), size_t(9));
ASSERT_EQ(compilationFlags.size(), size_t(10));

ASSERT_EQ(compilationFlags.at(0), "-I"s);
ASSERT_EQ(compilationFlags.at(1), "foo"s);
ASSERT_EQ(compilationFlags.at(2), "-I"s);
ASSERT_EQ(compilationFlags.at(3), "bar"s);
ASSERT_EQ(compilationFlags.at(4), "-c"s);
ASSERT_EQ(compilationFlags.at(5), "-isystem"s);
ASSERT_EQ(compilationFlags.at(6), "/usr/local/include"s);
ASSERT_EQ(compilationFlags.at(7), "-isystem"s);
ASSERT_EQ(compilationFlags.at(8), "/usr/include"s);
ASSERT_EQ(compilationFlags.at(5), "foobar.cpp"s);
ASSERT_EQ(compilationFlags.at(6), "-isystem"s);
ASSERT_EQ(compilationFlags.at(7), "/usr/local/include"s);
ASSERT_EQ(compilationFlags.at(8), "-isystem"s);
ASSERT_EQ(compilationFlags.at(9), "/usr/include"s);
}

TEST(CompilationDatabaseFromFile, parsesCompilationFlagsFromClangMJCommandValid) {
Expand All @@ -95,12 +97,13 @@ TEST(CompilationDatabaseFromFile, parsesCompilationFlagsFromClangMJCommandValid)
const std::string file("/tmp/main.cpp");
auto compilationFlags = database.compilationFlagsForFile(file);

ASSERT_EQ(compilationFlags.size(), size_t(20));
ASSERT_EQ(compilationFlags.size(), size_t(21));
ASSERT_EQ(compilationFlags.at(0), "-xc++"s);
ASSERT_EQ(compilationFlags.at(1), "-fembed-bitcode=all"s);
ASSERT_EQ(compilationFlags.at(2), "-g"s);
ASSERT_EQ(compilationFlags.at(18), "-isystem"s);
ASSERT_EQ(compilationFlags.at(19), "/usr/include"s);
ASSERT_EQ(compilationFlags.at(1), "main.cpp"s);
ASSERT_EQ(compilationFlags.at(2), "-fembed-bitcode=all"s);
ASSERT_EQ(compilationFlags.at(3), "-g"s);
ASSERT_EQ(compilationFlags.at(19), "-isystem"s);
ASSERT_EQ(compilationFlags.at(20), "/usr/include"s);
}

TEST(CompilationDatabaseFromFile, parsesCompilationDatabaseWithEscapedQuotes) {
Expand All @@ -111,7 +114,7 @@ TEST(CompilationDatabaseFromFile, parsesCompilationDatabaseWithEscapedQuotes) {
const std::string file("/tmp/main.cpp");
auto compilationFlags = database.compilationFlagsForFile(file);

ASSERT_EQ(compilationFlags.size(), size_t(5));
ASSERT_EQ(compilationFlags.size(), size_t(6));
ASSERT_EQ(compilationFlags.at(0), "-DQT_CORE_LIB"s);
ASSERT_EQ(compilationFlags.at(1), "-DQT_TESTCASE_BUILDDIR=\"/src/builds/amd64-linux-mull\""s);
ASSERT_EQ(compilationFlags.at(2), "-o"s);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[
{
"directory": "@DIR@",
"command": "clang -I @INC@/include",
"command": "clang -I @INC@/include @DIR@/main.cpp",
"file": "main.cpp"
}
]
5 changes: 4 additions & 1 deletion tools/mull-cxx-ir-frontend/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 "")
set_target_properties(mull-cxx-ir-frontend-${LLVM_VERSION_MAJOR} PROPERTIES SUFFIX "")
install(TARGETS mull-cxx-ir-frontend-${LLVM_VERSION_MAJOR}
RUNTIME DESTINATION lib
)
3 changes: 2 additions & 1 deletion tools/mull-cxx-ir-frontend/mull-cxx-ir-frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ namespace {
class MullIRFrontend : public llvm::PassInfoMixin<MullIRFrontend> {
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();
}
};
Expand Down

0 comments on commit 6217cf2

Please sign in to comment.