Skip to content

Commit b7c3833

Browse files
committed
Add support for external variables
1 parent 0a217b7 commit b7c3833

File tree

10 files changed

+64
-7
lines changed

10 files changed

+64
-7
lines changed

server/src/Tests.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,4 +1160,9 @@ bool isUnnamed(char *name) {
11601160
bool Tests::MethodTestCase::isError() const {
11611161
return suiteName == ERROR_SUITE_NAME;
11621162
}
1163+
1164+
bool Tests::TypeAndVarName::operator<(const Tests::TypeAndVarName &other) const {
1165+
return varName < other.varName || (varName == other.varName && type.mTypeName() < other.type.mTypeName());
1166+
}
1167+
11631168
}

server/src/Tests.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,8 @@ namespace tests {
336336
TypeAndVarName(types::Type type, std::string varName)
337337
: type(std::move(type)), varName(std::move(varName)) {
338338
}
339+
340+
bool operator<(const TypeAndVarName &) const;
339341
};
340342

341343
struct MethodParam {
@@ -558,6 +560,7 @@ namespace tests {
558560
fs::path testHeaderFilePath;
559561
fs::path testSourceFilePath;
560562

563+
std::set<TypeAndVarName> externVariables;
561564
std::vector<Include> srcFileHeaders;
562565
std::vector<Include> headersBeforeMainHeader;
563566
std::optional<Include> mainHeader;

server/src/coverage/TestRunner.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <utils/stats/TestsExecutionStats.h>
12
#include "TestRunner.h"
23

34
#include "printers/DefaultMakefilePrinter.h"
@@ -152,6 +153,13 @@ grpc::Status TestRunner::runTests(bool withCoverage, const std::optional<std::ch
152153
exceptions.emplace_back(e);
153154
}
154155
});
156+
fs::remove(Paths::getGTestResultsJsonPath(projectContext));
157+
// StatsUtils::TestsExecutionStatsFileMap testsExecutionStats(projectContext, coverageGenerator.getTestResultMap(),
158+
// coverageGenerator.getCoverageMap());
159+
// printer::CSVPrinter printer = testsExecutionStats.toCSV();
160+
// FileSystemUtils::writeToFile(Paths::getExecutionStatsCSVPath(projectContext), printer.getStream().str());
161+
// LOG_S(INFO) << StringUtils::stringFormat("See execution stats here: %s",
162+
// Paths::getExecutionStatsCSVPath(projectContext));
155163
LOG_S(DEBUG) << "All run commands were executed";
156164
return Status::OK;
157165
}

server/src/fetchers/GlobalVariableUsageMatchCallback.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,6 @@ void GlobalVariableUsageMatchCallback::checkUsage(const MatchFinder::MatchResult
2020
Result.Nodes.getNodeAs<clang::VarDecl>(Matchers::GLOBAL_VARIABLE_USAGE)) {
2121
clang::QualType varType = pVarDecl->getType();
2222
std::string name = pVarDecl->getNameAsString();
23-
if (!pVarDecl->isKnownToBeDefined()) {
24-
LOG_S(DEBUG) << "Variable \"" << name << "\" was skipped - it has no definition.";
25-
return;
26-
}
2723
if (const auto *pFunctionDecl = Result.Nodes.getNodeAs<clang::FunctionDecl>(
2824
Matchers::FUNCTION_USED_GLOBAL_VARIABLE)) {
2925
if (varType.isConstant(pVarDecl->getASTContext())) {
@@ -62,12 +58,15 @@ void GlobalVariableUsageMatchCallback::handleUsage(const clang::FunctionDecl *fu
6258
return;
6359
}
6460

65-
auto &methods = (*parent->projectTests).at(sourceFilePath).methods;
66-
auto &method = methods[usage.functionName];
61+
auto &tests = (*parent->projectTests).at(sourceFilePath);
62+
auto &method = tests.methods[usage.functionName];
6763
const clang::QualType realParamType = varDecl->getType().getCanonicalType();
6864
const std::string usedParamTypeString = varDecl->getType().getAsString();
6965
types::Type paramType = types::Type(realParamType, usedParamTypeString, sourceManager);
7066
method.globalParams.emplace_back(paramType, usage.variableName, AlignmentFetcher::fetch(varDecl));
67+
if (varDecl->hasExternalStorage()) {
68+
tests.externVariables.insert({paramType, usage.variableName});
69+
}
7170
}
7271

7372
GlobalVariableUsageMatchCallback::Usage::Usage(std::string variableName, std::string functionName)

server/src/printers/KleePrinter.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ fs::path KleePrinter::writeTmpKleeFile(
113113
LOG_S(DEBUG) << "Writing tmpKleeFile for " << testedMethod << " inside " << tests.sourceFilePath;
114114

115115
bool hasMethod = false;
116-
for (const auto &[methodName,testMethod ]: tests.methods) {
116+
for (const auto &[methodName, testMethod]: tests.methods) {
117117
if (methodFilter(testMethod)) {
118118
hasMethod = true;
119119
}
@@ -143,6 +143,15 @@ fs::path KleePrinter::writeTmpKleeFile(
143143

144144
writeAccessPrivateMacros(typesHandler, tests, false);
145145

146+
CollectionUtils::apply(tests.externVariables, [this](const Tests::TypeAndVarName &var) {
147+
if (var.type.isArray()) {
148+
strDeclareArrayVar(var.type, var.varName, types::PointerUsage::KNOWN_SIZE);
149+
} else {
150+
strDeclareVar(var.type.mTypeName(), var.varName);
151+
}
152+
});
153+
ss << NL;
154+
146155
for (const auto &[methodName, testMethod] : tests.methods) {
147156
if (!methodFilter(testMethod)) {
148157
continue;

server/src/printers/TestsPrinter.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@ void TestsPrinter::joinToFinalCode(Tests &tests, const fs::path& generatedHeader
6161
resetStream();
6262
writeCopyrightHeader();
6363
genHeaders(tests, generatedHeaderPath);
64+
ss << NL;
65+
66+
CollectionUtils::apply(tests.externVariables, [this](const Tests::TypeAndVarName &var) {
67+
if (var.type.isArray()) {
68+
strDeclareArrayVar(var.type, var.varName, types::PointerUsage::KNOWN_SIZE);
69+
} else {
70+
strDeclareVar(var.type.mTypeName(), var.varName);
71+
}
72+
});
73+
6474
ss << "namespace " << PrinterUtils::TEST_NAMESPACE << " {\n";
6575

6676
for (const auto &commentBlock : tests.commentBlocks) {

server/src/utils/CollectionUtils.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,13 @@ namespace CollectionUtils {
135135
return result;
136136
}
137137

138+
template <typename Iterable, typename Functor>
139+
void apply(Iterable const &items, Functor &&functor) {
140+
for (auto it : items) {
141+
functor(it);
142+
}
143+
}
144+
138145
/**
139146
* @brief Transforms given collection to another by applying functor to each element.
140147
* @param items collection of type Collection with elements of type T.

server/test/framework/Regression_Tests.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,4 +359,12 @@ namespace {
359359
ASSERT_TRUE(status.ok()) << status.error_message();
360360
testUtils::checkMinNumberOfTests(testGen.tests, 1);
361361
}
362+
363+
TEST_F(Regression_Test, Extern_Variables) {
364+
fs::path source = getTestFilePath("issue-514.c");
365+
auto [testGen, status] = createTestForFunction(source, 5);
366+
367+
ASSERT_TRUE(status.ok()) << status.error_message();
368+
}
369+
362370
}

server/test/suites/regression/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,6 @@ target_compile_definitions(issue-276 PUBLIC EXPORT3=4)
4848
target_compile_definitions(issue-276 PUBLIC EXPORT4="4")
4949

5050
add_library(issue-195 issue-195.c)
51+
add_library(issue-514 issue-514.c)
5152

5253
set_target_properties(regression PROPERTIES LINK_WHAT_YOU_USE TRUE)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#define MAX_INDEX 10
2+
3+
extern unsigned g_arrayNumber[MAX_INDEX];
4+
5+
unsigned GetNum(unsigned index) {
6+
return g_arrayNumber[index];
7+
}

0 commit comments

Comments
 (0)