Skip to content

Commit

Permalink
Avoid miscompilation of variadic functions
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexDenisov authored and AlexDenisov committed Feb 19, 2022
1 parent aab6eed commit 0c8cebb
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/mull/Filters/Filters.h
Expand Up @@ -29,6 +29,7 @@ class Filters {
void enableFilePathFilter();
void enableGitDiffFilter();
void enableBlockAddressFilter();
void enableVariadicFunctionFilter();
CoverageFilter *enableCoverageFilter(const std::string &profileName,
const std::vector<std::string> &objects);

Expand Down
13 changes: 13 additions & 0 deletions include/mull/Filters/VariadicFunctionFilter.h
@@ -0,0 +1,13 @@
#pragma once

#include "mull/Filters/FunctionFilter.h"

namespace mull {

class VariadicFunctionFilter : public FunctionFilter {
public:
bool shouldSkip(llvm::Function *function) override;
std::string name() override;
~VariadicFunctionFilter() override = default;
};
} // namespace mull
1 change: 1 addition & 0 deletions lib/CMakeLists.txt
Expand Up @@ -83,6 +83,7 @@ set(mull_sources
Filters/BlockAddressFunctionFilter.cpp
Filters/Filters.cpp
Filters/CoverageFilter.cpp
Filters/VariadicFunctionFilter.cpp

JunkDetection/CXX/Visitors/ScalarValueVisitor.cpp
MutantRunner.cpp
Expand Down
1 change: 1 addition & 0 deletions lib/Driver.cpp
Expand Up @@ -346,6 +346,7 @@ void mull::mutateBitcode(llvm::Module &module) {
filters.enableFilePathFilter();
filters.enableGitDiffFilter();
filters.enableBlockAddressFilter();
filters.enableVariadicFunctionFilter();

std::string cxxCompilationFlags;
for (auto &flag : configuration.compilerFlags) {
Expand Down
7 changes: 7 additions & 0 deletions lib/Filters/Filters.cpp
Expand Up @@ -6,6 +6,7 @@
#include "mull/Filters/FilePathFilter.h"
#include "mull/Filters/GitDiffFilter.h"
#include "mull/Filters/NoDebugInfoFilter.h"
#include "mull/Filters/VariadicFunctionFilter.h"
#include <llvm/Support/FileSystem.h>
#include <sstream>

Expand Down Expand Up @@ -108,3 +109,9 @@ void Filters::enableBlockAddressFilter() {
storage.emplace_back(filter);
functionFilters.push_back(filter);
}

void Filters::enableVariadicFunctionFilter() {
auto filter = new mull::VariadicFunctionFilter;
storage.emplace_back(filter);
functionFilters.push_back(filter);
}
12 changes: 12 additions & 0 deletions lib/Filters/VariadicFunctionFilter.cpp
@@ -0,0 +1,12 @@
#include "mull/Filters/VariadicFunctionFilter.h"
#include <llvm/IR/Function.h>

using namespace mull;

bool VariadicFunctionFilter::shouldSkip(llvm::Function *function) {
return function->isVarArg();
}

std::string VariadicFunctionFilter::name() {
return "variadic functions";
}
4 changes: 2 additions & 2 deletions tests-lit/tests/filters/blockaddress/main.c
Expand Up @@ -17,5 +17,5 @@ int main(int argc, char **argv) {
// RUN: %clang_cc %pass_mull_ir_frontend -g %s -o %s.exe
// RUN: %s.exe | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=CHECK1
// CHECK1:label1
// RUN: %s.exe | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=CHECK2
// CHECK2:label1
// RUN: %s.exe x | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=CHECK2
// CHECK2:label2
56 changes: 56 additions & 0 deletions tests-lit/tests/filters/variadic-functions/main.c
@@ -0,0 +1,56 @@
// clang-format off
#include <stdarg.h>

extern unsigned long strlen(const char *s);
extern char *strcpy(char * dst, const char * src);
extern int printf(const char *, ...);
extern void abort();

static int a = 10;
static int b = 32;
static int c = 0;

void fill_in(const char *what, int n, ...) {
c = a + b;
va_list args;
va_start(args, n);
for (int i = 0; i < n; ++i) {
char *buf = va_arg(args, char *);
int w_len = strlen(what);
int b_len = strlen(buf);
if (w_len > b_len) {
printf("CRASHING\n");
abort();
}
strcpy(buf, what);
buf[i] = '_';
buf[b_len] = '\0';
}
va_end(args);
}

int main() {
char b1[16] = "initialize";
char b2[16] = "initialize";
char b3[16] = "initialize";
char b4[16] = "initialize";
fill_in("test", 4, b1, b2, b3, b4);
printf("%s\n", b1);
printf("%s\n", b2);
printf("%s\n", b3);
printf("%s\n", b4);
printf("%d\n", c);
return 0;
}

// RUN: %clang_cc %pass_mull_ir_frontend -g %s -o %s.exe
// RUN: %s.exe | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines
// CHECK:_est
// CHECK-NEXT:t_st
// CHECK-NEXT:te_t
// CHECK-NEXT:tes_
// CHECK-NEXT:42
// CHECK-EMPTY

// RUN: unset TERM; %mull_runner %s.exe | %filecheck %s --dump-input=fail --strict-whitespace --match-full-lines --check-prefix=CHECK_MUTANT
// CHECK_MUTANT:[info] No mutants found. Mutation score: infinitely high
3 changes: 3 additions & 0 deletions tests-lit/tests/filters/variadic-functions/mull.yml
@@ -0,0 +1,3 @@
mutators:
- cxx_add_to_sub
quiet: false

0 comments on commit 0c8cebb

Please sign in to comment.