Skip to content

Commit

Permalink
Add support for external variables
Browse files Browse the repository at this point in the history
  • Loading branch information
Lana243 committed Oct 31, 2022
1 parent 0a217b7 commit b7c3833
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 7 deletions.
5 changes: 5 additions & 0 deletions server/src/Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1160,4 +1160,9 @@ bool isUnnamed(char *name) {
bool Tests::MethodTestCase::isError() const {
return suiteName == ERROR_SUITE_NAME;
}

bool Tests::TypeAndVarName::operator<(const Tests::TypeAndVarName &other) const {
return varName < other.varName || (varName == other.varName && type.mTypeName() < other.type.mTypeName());
}

}
3 changes: 3 additions & 0 deletions server/src/Tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ namespace tests {
TypeAndVarName(types::Type type, std::string varName)
: type(std::move(type)), varName(std::move(varName)) {
}

bool operator<(const TypeAndVarName &) const;
};

struct MethodParam {
Expand Down Expand Up @@ -558,6 +560,7 @@ namespace tests {
fs::path testHeaderFilePath;
fs::path testSourceFilePath;

std::set<TypeAndVarName> externVariables;
std::vector<Include> srcFileHeaders;
std::vector<Include> headersBeforeMainHeader;
std::optional<Include> mainHeader;
Expand Down
8 changes: 8 additions & 0 deletions server/src/coverage/TestRunner.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <utils/stats/TestsExecutionStats.h>
#include "TestRunner.h"

#include "printers/DefaultMakefilePrinter.h"
Expand Down Expand Up @@ -152,6 +153,13 @@ grpc::Status TestRunner::runTests(bool withCoverage, const std::optional<std::ch
exceptions.emplace_back(e);
}
});
fs::remove(Paths::getGTestResultsJsonPath(projectContext));
// StatsUtils::TestsExecutionStatsFileMap testsExecutionStats(projectContext, coverageGenerator.getTestResultMap(),
// coverageGenerator.getCoverageMap());
// printer::CSVPrinter printer = testsExecutionStats.toCSV();
// FileSystemUtils::writeToFile(Paths::getExecutionStatsCSVPath(projectContext), printer.getStream().str());
// LOG_S(INFO) << StringUtils::stringFormat("See execution stats here: %s",
// Paths::getExecutionStatsCSVPath(projectContext));
LOG_S(DEBUG) << "All run commands were executed";
return Status::OK;
}
Expand Down
11 changes: 5 additions & 6 deletions server/src/fetchers/GlobalVariableUsageMatchCallback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ void GlobalVariableUsageMatchCallback::checkUsage(const MatchFinder::MatchResult
Result.Nodes.getNodeAs<clang::VarDecl>(Matchers::GLOBAL_VARIABLE_USAGE)) {
clang::QualType varType = pVarDecl->getType();
std::string name = pVarDecl->getNameAsString();
if (!pVarDecl->isKnownToBeDefined()) {
LOG_S(DEBUG) << "Variable \"" << name << "\" was skipped - it has no definition.";
return;
}
if (const auto *pFunctionDecl = Result.Nodes.getNodeAs<clang::FunctionDecl>(
Matchers::FUNCTION_USED_GLOBAL_VARIABLE)) {
if (varType.isConstant(pVarDecl->getASTContext())) {
Expand Down Expand Up @@ -62,12 +58,15 @@ void GlobalVariableUsageMatchCallback::handleUsage(const clang::FunctionDecl *fu
return;
}

auto &methods = (*parent->projectTests).at(sourceFilePath).methods;
auto &method = methods[usage.functionName];
auto &tests = (*parent->projectTests).at(sourceFilePath);
auto &method = tests.methods[usage.functionName];
const clang::QualType realParamType = varDecl->getType().getCanonicalType();
const std::string usedParamTypeString = varDecl->getType().getAsString();
types::Type paramType = types::Type(realParamType, usedParamTypeString, sourceManager);
method.globalParams.emplace_back(paramType, usage.variableName, AlignmentFetcher::fetch(varDecl));
if (varDecl->hasExternalStorage()) {
tests.externVariables.insert({paramType, usage.variableName});
}
}

GlobalVariableUsageMatchCallback::Usage::Usage(std::string variableName, std::string functionName)
Expand Down
11 changes: 10 additions & 1 deletion server/src/printers/KleePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ fs::path KleePrinter::writeTmpKleeFile(
LOG_S(DEBUG) << "Writing tmpKleeFile for " << testedMethod << " inside " << tests.sourceFilePath;

bool hasMethod = false;
for (const auto &[methodName,testMethod ]: tests.methods) {
for (const auto &[methodName, testMethod]: tests.methods) {
if (methodFilter(testMethod)) {
hasMethod = true;
}
Expand Down Expand Up @@ -143,6 +143,15 @@ fs::path KleePrinter::writeTmpKleeFile(

writeAccessPrivateMacros(typesHandler, tests, false);

CollectionUtils::apply(tests.externVariables, [this](const Tests::TypeAndVarName &var) {
if (var.type.isArray()) {
strDeclareArrayVar(var.type, var.varName, types::PointerUsage::KNOWN_SIZE);
} else {
strDeclareVar(var.type.mTypeName(), var.varName);
}
});
ss << NL;

for (const auto &[methodName, testMethod] : tests.methods) {
if (!methodFilter(testMethod)) {
continue;
Expand Down
10 changes: 10 additions & 0 deletions server/src/printers/TestsPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ void TestsPrinter::joinToFinalCode(Tests &tests, const fs::path& generatedHeader
resetStream();
writeCopyrightHeader();
genHeaders(tests, generatedHeaderPath);
ss << NL;

CollectionUtils::apply(tests.externVariables, [this](const Tests::TypeAndVarName &var) {
if (var.type.isArray()) {
strDeclareArrayVar(var.type, var.varName, types::PointerUsage::KNOWN_SIZE);
} else {
strDeclareVar(var.type.mTypeName(), var.varName);
}
});

ss << "namespace " << PrinterUtils::TEST_NAMESPACE << " {\n";

for (const auto &commentBlock : tests.commentBlocks) {
Expand Down
7 changes: 7 additions & 0 deletions server/src/utils/CollectionUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ namespace CollectionUtils {
return result;
}

template <typename Iterable, typename Functor>
void apply(Iterable const &items, Functor &&functor) {
for (auto it : items) {
functor(it);
}
}

/**
* @brief Transforms given collection to another by applying functor to each element.
* @param items collection of type Collection with elements of type T.
Expand Down
8 changes: 8 additions & 0 deletions server/test/framework/Regression_Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,4 +359,12 @@ namespace {
ASSERT_TRUE(status.ok()) << status.error_message();
testUtils::checkMinNumberOfTests(testGen.tests, 1);
}

TEST_F(Regression_Test, Extern_Variables) {
fs::path source = getTestFilePath("issue-514.c");
auto [testGen, status] = createTestForFunction(source, 5);

ASSERT_TRUE(status.ok()) << status.error_message();
}

}
1 change: 1 addition & 0 deletions server/test/suites/regression/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ target_compile_definitions(issue-276 PUBLIC EXPORT3=4)
target_compile_definitions(issue-276 PUBLIC EXPORT4="4")

add_library(issue-195 issue-195.c)
add_library(issue-514 issue-514.c)

set_target_properties(regression PROPERTIES LINK_WHAT_YOU_USE TRUE)
7 changes: 7 additions & 0 deletions server/test/suites/regression/issue-514.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#define MAX_INDEX 10

extern unsigned g_arrayNumber[MAX_INDEX];

unsigned GetNum(unsigned index) {
return g_arrayNumber[index];
}

0 comments on commit b7c3833

Please sign in to comment.