Skip to content

Commit 90d9f40

Browse files
authored
Alter variable wrappers generation and usage (#617)
* Alter variable wrappers generation and usage
1 parent 484a2fd commit 90d9f40

File tree

8 files changed

+126
-9
lines changed

8 files changed

+126
-9
lines changed

Diff for: server/src/clang-utils/SourceToHeaderMatchCallback.cpp

+26-9
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,8 @@ void SourceToHeaderMatchCallback::generateInternal(const VarDecl *decl) const {
236236
policy.SuppressInitializers = 1;
237237

238238
/*
239-
* extern "C" (*var_wrapper);
240-
* &DECL = *var_wrapper;
239+
* extern "C" (*get_var_wrapper);
240+
* &DECL = *get_var_wrapper();
241241
*/
242242

243243
std::string name = decl->getNameAsString();
@@ -252,9 +252,13 @@ void SourceToHeaderMatchCallback::generateInternal(const VarDecl *decl) const {
252252
std::string wrapperPointerDecl =
253253
getRenamedDeclarationAsString(decl, policy, wrapperPointerName);
254254
std::string refDecl = getRenamedDeclarationAsString(decl, policy, refName);
255+
PrinterUtils::removeThreadLocalQualifiers(refDecl);
255256

256-
*internalStream << "extern \"C\" " << wrapperPointerDecl << ";\n";
257-
*internalStream << refDecl << " = " << wrapperPointerName << ";\n";
257+
std::string returnTypeName = PrinterUtils::getPointerMangledName(name);
258+
std::string getterName = PrinterUtils::getterName(wrapperName);
259+
*internalStream << generateTypedefForGetterReturnType(decl, policy, returnTypeName);
260+
*internalStream << "extern \"C\" " << PrinterUtils::getterDecl(returnTypeName, wrapperName) << ";\n";
261+
*internalStream << stringFormat("%s = *%s();\n", refDecl, getterName);
258262
}
259263

260264
void SourceToHeaderMatchCallback::generateWrapper(const FunctionDecl *decl) const {
@@ -295,15 +299,18 @@ void SourceToHeaderMatchCallback::generateWrapper(const VarDecl *decl) const {
295299
policy.SuppressInitializers = 1;
296300

297301
/*
298-
* (*var_wrapper) = &var;
302+
* get_var_wrapper {
303+
* return &var;
304+
* }
299305
*/
300306

301307
std::string name = decl->getNameAsString();
302308
std::string wrapperName = PrinterUtils::wrapperName(name, projectContext, sourceFilePath);
303-
std::string wrapperPointerName = stringFormat("(*%s)", wrapperName);
304-
std::string wrapperPointerDecl =
305-
getRenamedDeclarationAsString(decl, policy, wrapperPointerName);
306-
*wrapperStream << wrapperPointerDecl << " = &" << name << ";\n";
309+
std::string returnTypeName = PrinterUtils::getPointerMangledName(name);
310+
*wrapperStream << generateTypedefForGetterReturnType(decl, policy, returnTypeName);
311+
*wrapperStream << PrinterUtils::getterDecl(returnTypeName, wrapperName) << " {\n";
312+
*wrapperStream << stringFormat("return &%s;\n", name);
313+
*wrapperStream << "}\n";
307314
}
308315

309316
void SourceToHeaderMatchCallback::generateUnnamedTypeDecls(const clang::RecordDecl *decl) const {
@@ -411,6 +418,16 @@ SourceToHeaderMatchCallback::getDefaultPrintingPolicy(const Decl *decl,
411418
return policy;
412419
}
413420

421+
std::string
422+
SourceToHeaderMatchCallback::generateTypedefForGetterReturnType(const clang::VarDecl *decl,
423+
const clang::PrintingPolicy &policy,
424+
const std::string &returnTypeName) const {
425+
std::string wrapperPointerName = stringFormat("(*%s)", returnTypeName);
426+
std::string wrapperPointerDecl = getRenamedDeclarationAsString(decl, policy, wrapperPointerName);
427+
PrinterUtils::removeThreadLocalQualifiers(wrapperPointerDecl);
428+
return "typedef " + wrapperPointerDecl + ";\n";
429+
}
430+
414431
std::string
415432
SourceToHeaderMatchCallback::getRenamedDeclarationAsString(const clang::NamedDecl *decl,
416433
clang::PrintingPolicy const &policy,

Diff for: server/src/clang-utils/SourceToHeaderMatchCallback.h

+4
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ class SourceToHeaderMatchCallback : public clang::ast_matchers::MatchFinder::Mat
9393

9494
void generateUnnamedTypeDecls(const clang::RecordDecl *decl) const;
9595

96+
std::string generateTypedefForGetterReturnType(const clang::VarDecl *decl,
97+
const clang::PrintingPolicy &policy,
98+
const std::string &returnTypeName) const;
99+
96100
std::string getRenamedDeclarationAsString(const clang::NamedDecl *decl,
97101
clang::PrintingPolicy const &policy,
98102
std::string const &name) const;

Diff for: server/src/utils/PrinterUtils.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ namespace PrinterUtils {
2222
return StringUtils::stringFormat("%s_%s", declName, mangledPath);
2323
}
2424

25+
std::string getterName(const std::string &wrapperName) {
26+
return "get_" + wrapperName;
27+
}
28+
29+
std::string getterDecl(const std::string &returnTypeName,
30+
const std::string &wrapperName) {
31+
std::string gName = getterName(wrapperName);
32+
return StringUtils::stringFormat("%s %s()", returnTypeName, gName);
33+
}
34+
2535
std::string getFieldAccess(const std::string &objectName, const types::Field &field) {
2636
if (field.name.empty()) {
2737
return objectName;
@@ -89,6 +99,10 @@ namespace PrinterUtils {
8999
}
90100
}
91101

102+
std::string getPointerMangledName(const std::string &name) {
103+
return name + "_pointer";
104+
}
105+
92106
std::string getParamMangledName(const std::string& paramName, const std::string& methodName) {
93107
return methodName + "_" + paramName + "_arg";
94108
}
@@ -128,4 +142,8 @@ namespace PrinterUtils {
128142
std::string getFileWriteBytesParamKTestJSON(char fileName) {
129143
return StringUtils::stringFormat("%c-data-write", fileName);
130144
}
145+
146+
void removeThreadLocalQualifiers(std::string &decl) {
147+
StringUtils::replaceAll(decl, "__thread ", "");
148+
}
131149
}

Diff for: server/src/utils/PrinterUtils.h

+8
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ namespace PrinterUtils {
6868
utbot::ProjectContext const &projectContext,
6969
const fs::path &sourceFilePath);
7070

71+
std::string getterName(const std::string &wrapperName);
72+
73+
std::string getterDecl(const std::string &returnTypeName,
74+
const std::string &wrapperName);
75+
7176
std::string getFieldAccess(const std::string &objectName, const types::Field &field);
7277

7378
std::string fillVarName(std::string const &temp, std::string const &varName);
@@ -76,6 +81,7 @@ namespace PrinterUtils {
7681

7782
std::string wrapUserValue(const testsgen::ValidationType &type, const std::string &value);
7883

84+
std::string getPointerMangledName(const std::string &name);
7985
std::string getParamMangledName(const std::string &paramName, const std::string &methodName);
8086
std::string getReturnMangledName(const std::string &methodName);
8187
std::string getReturnMangledTypeName(const std::string& methodName);
@@ -99,6 +105,8 @@ namespace PrinterUtils {
99105
std::string getFileReadBytesParamKTestJSON(char fileName);
100106
std::string getFileWriteBytesParamKTestJSON(char fileName);
101107

108+
void removeThreadLocalQualifiers(std::string &decl);
109+
102110
const std::string LAZYRENAME = "utbotInnerVar";
103111
const std::string UTBOT_ARGC = "utbot_argc";
104112
const std::string UTBOT_ARGV = "utbot_argv";

Diff for: server/test/framework/Server_Tests.cpp

+38
Original file line numberDiff line numberDiff line change
@@ -2217,4 +2217,42 @@ namespace {
22172217
StatusCountMap expectedStatusCountMap{ { testsgen::TEST_PASSED, 3 } };
22182218
testUtils::checkStatuses(resultsMap, tests);
22192219
}
2220+
2221+
TEST_F(Server_Test, Run_Tests_For_Thread_Local) {
2222+
fs::path thread_local_c = getTestFilePath("thread_local.c");
2223+
auto request = testUtils::createFileRequest(projectName, suitePath, buildDirRelativePath,
2224+
srcPaths, thread_local_c,
2225+
GrpcUtils::UTBOT_AUTO_TARGET_PATH, true, false);
2226+
auto testGen = FileTestGen(*request, writer.get(), TESTMODE);
2227+
Status status = Server::TestsGenServiceImpl::ProcessBaseTestRequest(testGen, writer.get());
2228+
ASSERT_TRUE(status.ok()) << status.error_message();
2229+
EXPECT_GE(testUtils::getNumberOfTests(testGen.tests), 3);
2230+
2231+
fs::path testsDirPath = getTestFilePath("tests");
2232+
2233+
fs::path thread_local_test_cpp = Paths::sourcePathToTestPath(
2234+
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath),
2235+
thread_local_c);
2236+
auto testFilter = GrpcUtils::createTestFilterForFile(thread_local_test_cpp);
2237+
auto runRequest = testUtils::createCoverageAndResultsRequest(
2238+
projectName, suitePath, testsDirPath, buildDirRelativePath, std::move(testFilter));
2239+
2240+
static auto coverageAndResultsWriter =
2241+
std::make_unique<ServerCoverageAndResultsWriter>(nullptr);
2242+
CoverageAndResultsGenerator coverageGenerator{ runRequest.get(),
2243+
coverageAndResultsWriter.get() };
2244+
utbot::SettingsContext settingsContext{
2245+
true, false, 45, 0, false, false, ErrorMode::FAILING, false
2246+
};
2247+
coverageGenerator.generate(false, settingsContext);
2248+
2249+
EXPECT_FALSE(coverageGenerator.hasExceptions());
2250+
ASSERT_TRUE(coverageGenerator.getCoverageMap().empty());
2251+
2252+
auto resultsMap = coverageGenerator.getTestResultMap();
2253+
auto tests = coverageGenerator.getTestsToLaunch();
2254+
2255+
StatusCountMap expectedStatusCountMap{ { testsgen::TEST_PASSED, 3 } };
2256+
testUtils::checkStatuses(resultsMap, tests);
2257+
}
22202258
}

Diff for: server/test/suites/server/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ add_executable(server
2626
simple_unions.c
2727
struct_with_union.c
2828
structs_with_pointers.c
29+
thread_local.c
2930
complex_structs.c
3031
typedefs.c
3132
types.c

Diff for: server/test/suites/server/thread_local.c

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include "thread_local.h"
2+
3+
__thread int thread_local_id;
4+
5+
void set_id(int id) {
6+
thread_local_id = id + 5;
7+
}
8+
9+
__thread char thread_local_bytes[8];
10+
void set_bytes(char bytes[8]) {
11+
for (int i = 0; i < 8; ++i) {
12+
thread_local_bytes[i] = bytes[7 - i];
13+
}
14+
}
15+
16+
__thread struct ThreadLocalStorage thread_local_storage;
17+
void set_storage(struct ThreadLocalStorage storage) {
18+
thread_local_storage.fld = - storage.fld - 10;
19+
}

Diff for: server/test/suites/server/thread_local.h

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef UNITTESTBOT_THREAD_LOCAL_H
2+
#define UNITTESTBOT_THREAD_LOCAL_H
3+
4+
struct ThreadLocalStorage {
5+
int fld;
6+
};
7+
8+
void set_id(int id);
9+
10+
void set_bytes(char bytes[8]);
11+
12+
#endif // UNITTESTBOT_THREAD_LOCAL_H

0 commit comments

Comments
 (0)