Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate correct stub names for inner function pointers of structs #612

Merged
merged 4 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions server/src/printers/Printer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,9 @@ namespace printer {
auto methodCopy = method;
methodCopy.name = method.name;

std::string stubSymbolicVarName = getStubSymbolicVarName(nameForStub);
std::string stubSymbolicVarName = StubsUtils::getStubSymbolicVarName(nameForStub);
if (!types::TypesHandler::omitMakeSymbolic(method.returnType)) {
stubSymbolicVarName = getStubSymbolicVarName(methodName + "_" + nameForStub);
stubSymbolicVarName = StubsUtils::getStubSymbolicVarName(methodName + "_" + nameForStub);
strDeclareArrayVar(types::Type::createArray(method.returnType), stubSymbolicVarName,
types::PointerUsage::PARAMETER);
}
Expand Down Expand Up @@ -447,10 +447,6 @@ namespace printer {
return ss;
}

std::string Printer::getStubSymbolicVarName(const std::string &methodName) {
return methodName + PrinterUtils::KLEE_SYMBOLIC_SUFFIX;
}

Printer::Stream Printer::strKleeMakeSymbolic(const std::string &varName, bool needAmpersand, SRef pseudoName) {
auto pointer = (needAmpersand ? "&" : "") + varName;
auto size = "sizeof(" + varName + ")";
Expand Down
2 changes: 0 additions & 2 deletions server/src/printers/Printer.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,6 @@ namespace printer {
const std::string &nameForStub,
bool makeStatic = false);

static std::string getStubSymbolicVarName(const std::string &methodName);

Stream strKleeMakeSymbolic(SRef varName, bool needAmpersand, SRef pseudoName);

static inline std::string getTypedefFunctionPointer(const std::string &parentFunctionName,
Expand Down
2 changes: 1 addition & 1 deletion server/src/printers/StubsPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Stubs printer::StubsPrinter::genStubFile(const tests::Tests &tests,
}

if (!typesHandler.omitMakeSymbolic(methodCopy.returnType)) {
std::string stubSymbolicVarName = getStubSymbolicVarName(method.name);
std::string stubSymbolicVarName = StubsUtils::getStubSymbolicVarName(method.name);
strDeclareArrayVar(types::Type::createArray(method.returnType), stubSymbolicVarName,
types::PointerUsage::PARAMETER);
}
Expand Down
1 change: 1 addition & 0 deletions server/src/printers/StubsPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "ProjectContext.h"
#include "stubs/Stubs.h"
#include "types/Types.h"
#include "utils/StubsUtils.h"

namespace printer {
class StubsPrinter : Printer {
Expand Down
2 changes: 1 addition & 1 deletion server/src/printers/TestsPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ void TestsPrinter::genCode(Tests::MethodDescription &methodDescription,

static std::string getTestName(const Tests::MethodDescription &methodDescription, int testNum) {
std::string renamedMethodDescription = KleeUtils::getRenamedOperator(methodDescription.name);
StringUtils::replaceAll(renamedMethodDescription, ':', '_');
StringUtils::replaceColon(renamedMethodDescription);
std::string testBaseName = methodDescription.isClassMethod()
? StringUtils::stringFormat("%s_%s",
methodDescription.classObj->type.typeName(),
Expand Down
2 changes: 1 addition & 1 deletion server/src/types/TypesResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ std::string TypesResolver::getFullname(const clang::TagDecl *TD, const clang::Qu
if (!fullname[parentID].empty()) {
fullname[id] = fullname[parentID] + "::" + fullname[id];
if (typeDeclNeeded) {
StringUtils::replaceAll(fullname[id], "::", "_");
StringUtils::replaceColon(fullname[id]);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion server/src/utils/KleeUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ namespace KleeUtils {
bool needToMangle,
bool isWrapped) {
std::string methodNewName = methodName;
StringUtils::replaceAll(methodNewName, ':', '_');
StringUtils::replaceColon(methodNewName);
methodNewName = getRenamedOperator(methodNewName);
if (isWrapped) {
methodNewName += PrinterUtils::WRAPPED_SUFFIX;
Expand Down
4 changes: 4 additions & 0 deletions server/src/utils/StringUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ namespace StringUtils {
}
}

void replaceColon(std::string &str) {
replaceAll(str, "::", "_");
}

bool isPrintable(int code) {
if (std::numeric_limits<char>::is_signed && code < 0) {
code += 256;
Expand Down
2 changes: 2 additions & 0 deletions server/src/utils/StringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ namespace StringUtils {

void replaceAll(std::string &str, const std::string &from, const std::string &to);

void replaceColon(std::string &str);

/**
* Returns true if char literal can be printed to .cpp file as is, false otherwise.
* @param value - given character code
Expand Down
5 changes: 4 additions & 1 deletion server/src/utils/StubsUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ namespace StubsUtils {
}

std::string getStubSymbolicVarName(const std::string &methodName) {
return methodName + PrinterUtils::KLEE_SYMBOLIC_SUFFIX;
std::string stubName = methodName + PrinterUtils::KLEE_SYMBOLIC_SUFFIX;
StringUtils::replaceColon(stubName);
return stubName;
}

std::string getFunctionPointerAsStructFieldStubName(const std::string &structName,
Expand All @@ -28,6 +30,7 @@ namespace StubsUtils {
} else {
stubName = stubName.substr(1);
}
StringUtils::replaceColon(stubName);
return stubName;
}
}
38 changes: 38 additions & 0 deletions server/test/framework/Server_Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1986,6 +1986,44 @@ namespace {
testUtils::checkStatusesCount(resultMap, tests, expectedStatusCountMap);
}

TEST_F(Server_Test, Run_Tests_For_Complex_Structs) {
fs::path complex_structs_c = getTestFilePath("complex_structs.c");
auto request = testUtils::createFileRequest(projectName, suitePath, buildDirRelativePath,
srcPaths, complex_structs_c,
GrpcUtils::UTBOT_AUTO_TARGET_PATH, true, false);
auto testGen = FileTestGen(*request, writer.get(), TESTMODE);
Status status = Server::TestsGenServiceImpl::ProcessBaseTestRequest(testGen, writer.get());
ASSERT_TRUE(status.ok()) << status.error_message();
EXPECT_GE(testUtils::getNumberOfTests(testGen.tests), 12);

fs::path testsDirPath = getTestFilePath("tests");

fs::path complex_structs_test_cpp = Paths::sourcePathToTestPath(
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath),
complex_structs_c);
auto testFilter = GrpcUtils::createTestFilterForFile(complex_structs_test_cpp);
auto runRequest = testUtils::createCoverageAndResultsRequest(
projectName, suitePath, testsDirPath, buildDirRelativePath, std::move(testFilter));

static auto coverageAndResultsWriter =
std::make_unique<ServerCoverageAndResultsWriter>(nullptr);
CoverageAndResultsGenerator coverageGenerator{ runRequest.get(),
coverageAndResultsWriter.get() };
utbot::SettingsContext settingsContext{
true, false, 45, 0, false, false, ErrorMode::FAILING, false
};
coverageGenerator.generate(false, settingsContext);

EXPECT_FALSE(coverageGenerator.hasExceptions());
ASSERT_TRUE(coverageGenerator.getCoverageMap().empty());

auto resultsMap = coverageGenerator.getTestResultMap();
auto tests = coverageGenerator.getTestsToLaunch();

StatusCountMap expectedStatusCountMap{ { testsgen::TEST_PASSED, 12 } };
testUtils::checkStatuses(resultsMap, tests);
}

TEST_F(Server_Test, Run_Tests_For_Input_Output_C) {
fs::path input_output_c = getTestFilePath("input_output.c");
auto request = testUtils::createFileRequest(projectName, suitePath, buildDirRelativePath,
Expand Down
4 changes: 4 additions & 0 deletions server/test/suites/server/complex_structs.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,7 @@ struct One alphabet(int a) {
struct One res = {1, {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'}};
return res;
}

int st_access_s(struct StructWithFunctionPointer st) {
return st.s;
}
11 changes: 10 additions & 1 deletion server/test/suites/server/complex_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ struct StructWithArrays {
int a[10];
};

struct StructWithFunctionPointer {
int s;
struct FunctionPointer {
void *(*plain) (int);
} fptr;
};

struct One {
int a;
char str[12];
Expand All @@ -23,8 +30,10 @@ struct Three {

int struct_has_alphabet(struct One st);


char arrays_in_inner_structs(struct Three st);

struct One alphabet(int a);

int st_access_s(struct StructWithFunctionPointer st);

#endif // SIMPLE_TEST_PROJECT_COMPLEX_STRUCTS_H