Skip to content

Commit fbf6554

Browse files
committed
Add new functional
1 parent 4286bb4 commit fbf6554

File tree

2 files changed

+112
-59
lines changed

2 files changed

+112
-59
lines changed

server/src/Tests.cpp

Lines changed: 98 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -366,17 +366,16 @@ std::shared_ptr<StructValueView> KTestObjectParser::structView(const std::vector
366366
break;
367367
case TypeKind::OBJECT_POINTER: {
368368
std::string res = readBytesAsValueForType(byteArray, PointerWidthType,
369-
fieldStartOffset,
370-
PointerWidthSizeInBits);
371-
auto pointerIterator = std::find_if(lazyPointersArray.begin(), lazyPointersArray.end(), [&fieldStartOffset] (const Pointer &ptr) {
372-
return ptr.offset == fieldStartOffset / 8;
373-
});
374-
std::optional<Pointer> pointerField = (pointerIterator == lazyPointersArray.end() ? std::nullopt : std::optional(*pointerIterator));
375-
subViews.push_back(getLazyPointerView(objects, pointerField, initReferences,
376-
PrinterUtils::getFieldAccess(name, field), res, field.type));
377-
}
378-
break;
379-
case TypeKind::FUNCTION_POINTER:
369+
fieldStartOffset, PointerWidthSizeInBits);
370+
auto pointerIterator =
371+
std::find_if(lazyPointersArray.begin(), lazyPointersArray.end(),
372+
[&fieldStartOffset](const Pointer &ptr) {
373+
return ptr.offset == fieldStartOffset / 8;
374+
});
375+
subViews.push_back(getLazyPointerView(objects, initReferences, PrinterUtils::getFieldAccess(name, field), res, field.type,
376+
pointerIterator != lazyPointersArray.end()));
377+
} break;
378+
case TypeKind::FUNCTION_POINTER:
380379
subViews.push_back(functionPointerView(curStruct.name, field.name));
381380
break;
382381
case TypeKind::UNKNOWN:
@@ -569,7 +568,7 @@ static std::string getSuiteName(const UTBotKTest::Status &status,
569568
return Tests::DEFAULT_SUITE_NAME;
570569
}
571570

572-
size_t KTestObjectParser::findFieldIndex(const StructInfo &structInfo, size_t offsetInBits) {
571+
size_t KTestObjectParser::findFieldIndex(const StructInfo &structInfo, size_t offsetInBits) const {
573572
size_t indField = std::upper_bound(structInfo.fields.begin(), structInfo.fields.end(), offsetInBits, [] (int offset, const Field &field) {
574573
return offset < field.offset;
575574
}) - structInfo.fields.begin();
@@ -602,8 +601,16 @@ void KTestObjectParser::addToOrder(const std::vector<UTBotKTestObject> &objects,
602601
LOG_S(WARNING) << message;
603602
}
604603

604+
bool KTestObjectParser::pointToStruct(const types::Type &pointerType, const UTBotKTestObject &goal) const {
605+
// In different situations we may point on the whole struct or on the field with assignment 0
606+
size_t fieldSizeInBits = typesHandler.typeSize(pointerType.baseTypeObj(1));
607+
size_t pointerVarSizeInBytes = goal.bytes.size();
608+
return SizeUtils::bytesToBits(pointerVarSizeInBytes) == fieldSizeInBits;
609+
}
610+
605611
void KTestObjectParser::assignTypeUnnamedVar(Tests::MethodTestCase &testCase,
606-
const Tests::MethodDescription &methodDescription) {
612+
const Tests::MethodDescription &methodDescription,
613+
std::vector<std::optional<Tests::TypeAndVarName>> &objects) {
607614
std::queue<JsonIndAndParam> order;
608615
std::vector<bool> visited(testCase.objects.size(), false);
609616
for (size_t paramInd = 0; paramInd < testCase.paramValues.size(); paramInd++) {
@@ -617,12 +624,14 @@ void KTestObjectParser::assignTypeUnnamedVar(Tests::MethodTestCase &testCase,
617624
while (!order.empty()) {
618625
auto curType = order.front();
619626
order.pop();
627+
std::string name = testCase.objects[curType.jsonInd].name;
620628
types::Type paramType = curType.param.type;
629+
objects[curType.jsonInd] = { paramType, name };
630+
621631
if (testCase.objects[curType.jsonInd].is_lazy) {
622632
if (types::TypesHandler::baseTypeIsVoid(paramType)) {
623633
throw UnImplementedException("Lazy variable has baseType=void");
624634
}
625-
std::string name = testCase.objects[curType.jsonInd].name;
626635

627636
std::vector<char> byteValue = testCase.objects[curType.jsonInd].bytes;
628637
Tests::TypeAndVarName typeAndVarName{ paramType, name };
@@ -636,37 +645,38 @@ void KTestObjectParser::assignTypeUnnamedVar(Tests::MethodTestCase &testCase,
636645
}
637646

638647
for (auto const &[offset, indObj, indexOffset] : testCase.objects[curType.jsonInd].pointers) {
648+
if (indexOffset != 0) {
649+
continue;
650+
}
651+
types::Type fieldType =
652+
traverseLazyInStruct(paramType, SizeUtils::bytesToBits(offset)).type;
653+
if (!pointToStruct(fieldType, testCase.objects[indObj])) {
654+
continue;
655+
}
639656
if (!visited[indObj]) {
640-
types::Type fieldType =
641-
traverseLazyInStruct(visited, paramType, SizeUtils::bytesToBits(offset),
642-
testCase, methodDescription);
643-
Tests::MethodParam param = { fieldType, "", std::nullopt };
657+
Tests::MethodParam param = { fieldType.baseTypeObj(1), "", std::nullopt };
644658
order.emplace(indObj, param, curType.paramValue);
645659
visited[indObj] = true;
646660
}
647661
}
648662
}
649663
}
650664

651-
types::Type KTestObjectParser::traverseLazyInStruct(std::vector<bool> &visited,
652-
const types::Type &curVarType,
653-
size_t offsetInBits,
654-
const Tests::MethodTestCase &testCase,
655-
const Tests::MethodDescription &methodDescription) {
665+
Tests::TypeAndVarName KTestObjectParser::traverseLazyInStruct(
666+
const types::Type &curVarType, size_t offsetInBits, const std::string &curVarName) const {
656667
switch (typesHandler.getTypeKind(curVarType)) {
657668
case TypeKind::STRUCT_LIKE: {
658669
const types::StructInfo &structInfo = typesHandler.getStructInfo(curVarType);
659670
size_t indField = findFieldIndex(structInfo, offsetInBits);
660671
const types::Field &next = structInfo.fields[indField];
661-
return traverseLazyInStruct(visited, next.type, offsetInBits - next.offset, testCase,
662-
methodDescription);
672+
return traverseLazyInStruct(next.type, offsetInBits - next.offset, PrinterUtils::getFieldAccess(curVarName, next));
663673
}
664674
case TypeKind::OBJECT_POINTER: {
665675
LOG_IF_S(ERROR, offsetInBits != 0) << "Offset not zero" << offsetInBits;
666-
return curVarType.baseTypeObj(1);
676+
return {curVarType, curVarName};
667677
}
668678
case TypeKind::PRIMITIVE: {
669-
return curVarType;
679+
return {curVarType, curVarName};
670680
}
671681
case TypeKind::ENUM:
672682
case TypeKind::FUNCTION_POINTER:
@@ -697,6 +707,50 @@ void KTestObjectParser::assignTypeStubVar(Tests::MethodTestCase &testCase,
697707
}
698708
}
699709

710+
void
711+
KTestObjectParser::assignAllLazyPointers(Tests::MethodTestCase &testCase,
712+
const std::vector<std::optional<Tests::TypeAndVarName>> &objects) const {
713+
for (size_t ind = 0; ind < testCase.objects.size(); ind++) {
714+
const auto &object = testCase.objects[ind];
715+
if (!objects[ind].has_value()) {
716+
continue;
717+
}
718+
for (const auto &pointer : object.pointers) {
719+
720+
Tests::TypeAndVarName fromPtr = traverseLazyInStruct(objects[ind]->type, SizeUtils::bytesToBits(pointer.offset), objects[ind]->varName);
721+
if (!objects[pointer.index].has_value()) {
722+
continue;
723+
}
724+
std::string toPtrName;
725+
726+
if (pointer.indexOffset == 0 && pointToStruct(fromPtr.type, testCase.objects[pointer.index])) {
727+
toPtrName = objects[pointer.index]->varName;
728+
} else {
729+
toPtrName = traverseLazyInStruct(objects[pointer.index]->type, SizeUtils::bytesToBits(pointer.indexOffset), objects[pointer.index]->varName).varName;
730+
}
731+
732+
testCase.lazyReferences.emplace_back(fromPtr.varName, toPtrName,
733+
PrinterUtils::initializePointerToVar(fromPtr.type.baseType(),
734+
toPtrName,
735+
fromPtr.type.getDimension()));
736+
}
737+
}
738+
739+
/*
740+
* if (!lazyPointer && ptr_element != objects.end()) {
741+
initReferences.emplace_back(name, ptr_element->name,
742+
PrinterUtils::initializePointerToVar(paramType.baseType(),
743+
ptr_element->name,
744+
paramType.getDimension()));
745+
}
746+
if (lazyPointer || ptr_element != objects.end()) {
747+
res = PrinterUtils::C_NULL;
748+
}
749+
return std::make_shared<JustValueView>(
750+
PrinterUtils::initializePointer(paramType.baseType(), res, paramType.getDimension()));
751+
*/
752+
}
753+
700754
void KTestObjectParser::parseTestCases(const UTBotKTestList &cases,
701755
bool filterByLineFlag,
702756
Tests::MethodDescription &methodDescription,
@@ -774,8 +828,10 @@ void KTestObjectParser::parseTestCases(const UTBotKTestList &cases,
774828
traceStream << "\treturn: " << testCase.returnValue.view->getEntryValue(nullptr);
775829
LOG_S(MAX) << traceStream.str();
776830

777-
assignTypeUnnamedVar(testCase, methodDescription);
831+
std::vector<std::optional<Tests::TypeAndVarName>> objectsValues(testCase.objects.size());
832+
assignTypeUnnamedVar(testCase, methodDescription, objectsValues);
778833
assignTypeStubVar(testCase, methodDescription);
834+
assignAllLazyPointers(testCase, objectsValues);
779835

780836
methodDescription.testCases.push_back(testCase);
781837
methodDescription.suiteTestCases[testCase.suiteName].push_back(testCase.testIndex);
@@ -1098,7 +1154,7 @@ std::shared_ptr<AbstractValueView> KTestObjectParser::testParameterView(
10981154
if (usage == types::PointerUsage::LAZY) {
10991155
std::string res =
11001156
readBytesAsValueForType(rawData, PointerWidthType, 0, PointerWidthSizeInBits);
1101-
return getLazyPointerView(objects, (kleeParam.pointers.empty() ? std::nullopt : std::optional(kleeParam.pointers[0])), initReferences, param.varName, res, paramType);
1157+
return getLazyPointerView(objects, initReferences, param.varName, res, paramType, !kleeParam.pointers.empty());
11021158
} else if (types::TypesHandler::isCStringType(paramType)) {
11031159
return stringLiteralView(rawData);
11041160
} else if (paramType.kinds().size() > 2) {
@@ -1134,31 +1190,23 @@ std::shared_ptr<AbstractValueView> KTestObjectParser::testParameterView(
11341190

11351191
std::shared_ptr<AbstractValueView>
11361192
KTestObjectParser::getLazyPointerView(const std::vector<UTBotKTestObject> &objects,
1137-
const std::optional<Pointer> &lazyPointer,
11381193
std::vector<InitReference> &initReferences,
11391194
const std::string &name,
11401195
std::string res,
1141-
const Type &paramType) const {
1142-
1143-
if (lazyPointer) {
1144-
initReferences.emplace_back(
1145-
name, objects[lazyPointer->index].name,
1146-
PrinterUtils::initializePointerToVar(
1147-
paramType.baseType(), objects[lazyPointer->index].name, paramType.getDimension()));
1196+
const Type &paramType,
1197+
bool lazyPointer) const {
1198+
size_t ptr = std::stoull(res);
1199+
auto ptr_element =
1200+
std::find_if(objects.begin(), objects.end(),
1201+
[ptr](const UTBotKTestObject &object) { return object.address == ptr; });
1202+
if (!lazyPointer && ptr_element != objects.end()) {
1203+
initReferences.emplace_back(name, ptr_element->name,
1204+
PrinterUtils::initializePointerToVar(paramType.baseType(),
1205+
ptr_element->name,
1206+
paramType.getDimension()));
1207+
}
1208+
if (lazyPointer || ptr_element != objects.end()) {
11481209
res = PrinterUtils::C_NULL;
1149-
} else {
1150-
size_t ptr = std::stoull(res);
1151-
1152-
auto ptr_element = std::find_if(objects.begin(), objects.end(), [ptr] (const UTBotKTestObject &object) {
1153-
return object.address == ptr;
1154-
});
1155-
if (ptr_element != objects.end()) {
1156-
initReferences.emplace_back(name, ptr_element->name,
1157-
PrinterUtils::initializePointerToVar(
1158-
paramType.baseType(), ptr_element->name,
1159-
paramType.getDimension()));
1160-
res = PrinterUtils::C_NULL;
1161-
}
11621210
}
11631211
return std::make_shared<JustValueView>(
11641212
PrinterUtils::initializePointer(paramType.baseType(), res, paramType.getDimension()));

server/src/Tests.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -809,26 +809,31 @@ namespace tests {
809809
std::queue<JsonIndAndParam> &order);
810810

811811
void assignTypeUnnamedVar(Tests::MethodTestCase &testCase,
812-
const Tests::MethodDescription &methodDescription);
812+
const Tests::MethodDescription &methodDescription,
813+
std::vector<std::optional<Tests::TypeAndVarName>> &objects);
813814

814815
void assignTypeStubVar(Tests::MethodTestCase &testCase,
815816
const Tests::MethodDescription &methodDescription);
816817

817-
size_t findFieldIndex(const types::StructInfo &structInfo, size_t offsetInBits);
818+
void
819+
assignAllLazyPointers(Tests::MethodTestCase &testCase,
820+
const std::vector<std::optional<Tests::TypeAndVarName>> &objects) const;
821+
822+
size_t findFieldIndex(const types::StructInfo &structInfo, size_t offsetInBits) const;
818823

819-
types::Type traverseLazyInStruct(std::vector<bool> &visited,
820-
const types::Type &curVarType,
821-
size_t offsetInBits,
822-
const Tests::MethodTestCase &testCase,
823-
const Tests::MethodDescription &methodDescription);
824+
Tests::TypeAndVarName traverseLazyInStruct(const types::Type &curVarType,
825+
size_t offsetInBits,
826+
const std::string &curVarName = "") const;
824827

825828
std::shared_ptr<AbstractValueView>
826829
getLazyPointerView(const std::vector<UTBotKTestObject> &objects,
827-
const std::optional<Pointer> &lazyPointer,
828830
std::vector<InitReference> &initReferences,
829831
const std::string &name,
830832
std::string res,
831-
const types::Type &paramType) const;
833+
const types::Type &paramType,
834+
bool lazyPointer) const;
835+
836+
bool pointToStruct(const types::Type &pointerType, const UTBotKTestObject &goal) const;
832837

833838
void
834839
getTestParamView(const Tests::MethodDescription &methodDescription, const std::vector<RawKleeParam> &rawKleeParams,

0 commit comments

Comments
 (0)