Skip to content

Commit 54ca965

Browse files
authored
External variables support (closes #514) (#522)
Add support for external variables
1 parent 9bf4766 commit 54ca965

File tree

12 files changed

+53
-5
lines changed

12 files changed

+53
-5
lines changed

server/src/Tests.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,4 +1163,9 @@ bool isUnnamed(char *name) {
11631163
bool Tests::MethodTestCase::isError() const {
11641164
return suiteName == ERROR_SUITE_NAME;
11651165
}
1166+
1167+
bool Tests::TypeAndVarName::operator<(const Tests::TypeAndVarName &other) const {
1168+
return varName < other.varName || (varName == other.varName && type.mTypeName() < other.type.mTypeName());
1169+
}
1170+
11661171
}

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: 1 addition & 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"

server/src/fetchers/GlobalVariableUsageMatchCallback.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ 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()) {
23+
if (!pVarDecl->isKnownToBeDefined() && !pVarDecl->isExternC()) {
2424
LOG_S(DEBUG) << "Variable \"" << name << "\" was skipped - it has no definition.";
2525
return;
2626
}
@@ -62,12 +62,15 @@ void GlobalVariableUsageMatchCallback::handleUsage(const clang::FunctionDecl *fu
6262
return;
6363
}
6464

65-
auto &methods = (*parent->projectTests).at(sourceFilePath).methods;
66-
auto &method = methods[usage.functionName];
65+
auto &tests = (*parent->projectTests).at(sourceFilePath);
66+
auto &method = tests.methods[usage.functionName];
6767
const clang::QualType realParamType = varDecl->getType().getCanonicalType();
6868
const std::string usedParamTypeString = varDecl->getType().getAsString();
6969
types::Type paramType = types::Type(realParamType, usedParamTypeString, sourceManager);
7070
method.globalParams.emplace_back(paramType, usage.variableName, AlignmentFetcher::fetch(varDecl));
71+
if (varDecl->isExternC() && !varDecl->isKnownToBeDefined()) {
72+
tests.externVariables.insert({paramType, usage.variableName});
73+
}
7174
}
7275

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

server/src/printers/KleePrinter.cpp

Lines changed: 4 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,9 @@ fs::path KleePrinter::writeTmpKleeFile(
143143

144144
writeAccessPrivateMacros(typesHandler, tests, false);
145145

146+
strDeclareSetOfVars(tests.externVariables);
147+
ss << NL;
148+
146149
for (const auto &[methodName, testMethod] : tests.methods) {
147150
if (!methodFilter(testMethod)) {
148151
continue;

server/src/printers/Printer.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,4 +674,15 @@ namespace printer {
674674
void Printer::writeCopyrightHeader() {
675675
ss << Copyright::GENERATED_C_CPP_FILE_HEADER << NL;
676676
}
677+
678+
Printer::Stream Printer::strDeclareSetOfVars(const std::set<Tests::TypeAndVarName> &vars) {
679+
for (const auto &var : vars) {
680+
if (var.type.isArray()) {
681+
strDeclareArrayVar(var.type, var.varName, types::PointerUsage::KNOWN_SIZE);
682+
} else {
683+
strDeclareVar(var.type.mTypeName(), var.varName);
684+
}
685+
}
686+
return ss;
687+
}
677688
}

server/src/printers/Printer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ namespace printer {
8888
std::optional<uint64_t> alignment = std::nullopt,
8989
bool complete = true);
9090

91+
Stream strDeclareSetOfVars(const std::set<Tests::TypeAndVarName> &vars);
92+
9193
Stream strAssignVar(std::string_view name, std::string_view value);
9294

9395
std::stringstream& checkOverflowStubArray(const std::string &cntCall);

server/src/printers/TestsPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ void TestsPrinter::joinToFinalCode(Tests &tests, const fs::path& generatedHeader
6161
resetStream();
6262
writeCopyrightHeader();
6363
genHeaders(tests, generatedHeaderPath);
64+
ss << NL;
65+
66+
strDeclareSetOfVars(tests.externVariables);
67+
6468
ss << "namespace " << PrinterUtils::TEST_NAMESPACE << " {\n";
6569

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

server/test/framework/Regression_Tests.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,4 +367,12 @@ namespace {
367367
ASSERT_TRUE(status.ok()) << status.error_message();
368368
testUtils::checkMinNumberOfTests(testGen.tests, 1);
369369
}
370+
371+
TEST_F(Regression_Test, Extern_Variables) {
372+
fs::path source = getTestFilePath("issue-514.c");
373+
auto [testGen, status] = createTestForFunction(source, 5);
374+
ASSERT_TRUE(status.ok()) << status.error_message();
375+
testUtils::checkMinNumberOfTests(testGen.tests, 2);
376+
}
377+
370378
}

server/test/framework/Server_Tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ namespace {
535535
} }));
536536
} else if (md.name == "use_globals") {
537537
EXPECT_GE(md.testCases.size(), 3);
538-
EXPECT_EQ(md.globalParams.size(), 2);
538+
EXPECT_EQ(md.globalParams.size(), 3);
539539
} else if (md.name == "use_global_array") {
540540
EXPECT_GE(md.testCases.size(), 3);
541541
EXPECT_EQ(md.globalParams.size(), 1);

0 commit comments

Comments
 (0)