diff --git a/include/revng/Model/RawFunctionType.h b/include/revng/Model/RawFunctionType.h index c99754bed..5e1213b4c 100644 --- a/include/revng/Model/RawFunctionType.h +++ b/include/revng/Model/RawFunctionType.h @@ -29,9 +29,7 @@ fields: - name: FinalStackOffset type: uint64_t - name: StackArgumentsType - reference: - pointeeType: model::Type - rootType: model::Binary + type: model::QualifiedType optional: true TUPLE-TREE-YAML */ diff --git a/lib/ABI/FunctionType.cpp b/lib/ABI/FunctionType.cpp index 8883c2179..b4c03eeeb 100644 --- a/lib/ABI/FunctionType.cpp +++ b/lib/ABI/FunctionType.cpp @@ -267,7 +267,8 @@ public: using namespace model; auto Type = UpcastableType::make(std::move(StackArguments)); - Result.StackArgumentsType = TheBinary->recordNewType(std::move(Type)); + Result.StackArgumentsType = { TheBinary->recordNewType(std::move(Type)), + {} }; } Result.FinalStackOffset = finalStackOffset(Arguments); @@ -448,12 +449,14 @@ private: } static llvm::SmallVector - convertStackArguments(model::TypePath StackArgumentTypes, + convertStackArguments(model::QualifiedType StackArgumentTypes, size_t IndexOffset) { - if (StackArgumentTypes.get() == nullptr) + revng_assert(StackArgumentTypes.Qualifiers.empty()); + auto *Unqualified = StackArgumentTypes.UnqualifiedType.get(); + if (not Unqualified) return {}; - auto *Pointer = llvm::dyn_cast(StackArgumentTypes.get()); + auto *Pointer = llvm::dyn_cast(Unqualified); revng_assert(Pointer != nullptr, "`RawFunctionType::StackArgumentsType` must be a struct"); const model::StructType &Types = *Pointer; @@ -849,15 +852,16 @@ Layout::Layout(const model::RawFunctionType &Function) { } // Lay stack arguments out. - if (Function.StackArgumentsType.isValid()) { - const model::Type *OriginalStackType = Function.StackArgumentsType.get(); + if (Function.StackArgumentsType.UnqualifiedType.isValid()) { + revng_assert(Function.StackArgumentsType.Qualifiers.empty()); + const model::Type *OriginalStackType = Function.StackArgumentsType + .UnqualifiedType.get(); auto *StackStruct = llvm::dyn_cast(OriginalStackType); revng_assert(StackStruct, "`RawFunctionType::StackArgumentsType` must be a struct."); typename Layout::Argument::StackSpan StackSpan{ 0, StackStruct->Size }; Arguments.emplace_back().Stack = std::move(StackSpan); - Arguments.back().Type = model::QualifiedType{ Function.StackArgumentsType, - {} }; + Arguments.back().Type = Function.StackArgumentsType; } // Fill callee saved registers. diff --git a/lib/Model/Type.cpp b/lib/Model/Type.cpp index 4e12c1c8a..59a770a2d 100644 --- a/lib/Model/Type.cpp +++ b/lib/Model/Type.cpp @@ -1106,6 +1106,12 @@ verifyImpl(VerifyHelper &VH, const RawFunctionType *T) { if (Preserved == Register::Invalid) rc_return VH.fail(); + if (not T->StackArgumentsType.Qualifiers.empty()) + rc_return VH.fail(); + if (T->StackArgumentsType.UnqualifiedType.isValid() + and not rc_recur T->StackArgumentsType.UnqualifiedType.get()->verify(VH)) + rc_return VH.fail(); + rc_return VH.maybeFail(T->CustomName.verify(VH)); } diff --git a/tests/abi/tools/revng-ensure-rft-equivalence/Main.cpp b/tests/abi/tools/revng-ensure-rft-equivalence/Main.cpp index 58977238a..600f7e407 100644 --- a/tests/abi/tools/revng-ensure-rft-equivalence/Main.cpp +++ b/tests/abi/tools/revng-ensure-rft-equivalence/Main.cpp @@ -93,12 +93,16 @@ int main(int Argc, char *Argv[]) { auto [Left, Right] = Pair; // Try and access the argument struct. - model::Type *LeftStackArguments = Left->StackArgumentsType.get(); - model::Type *RightStackArguments = Right->StackArgumentsType.get(); + revng_check(Left->StackArgumentsType.Qualifiers.empty()); + revng_check(Right->StackArgumentsType.Qualifiers.empty()); + model::Type *LeftStackArguments = Left->StackArgumentsType.UnqualifiedType + .get(); + model::Type *RightStackArguments = Right->StackArgumentsType.UnqualifiedType + .get(); // XOR the `bool`eans - make sure that either both functions have stack // argument or neither one does. - revng_assert(!LeftStackArguments == !RightStackArguments); + revng_check(!LeftStackArguments == !RightStackArguments); // Ignore function pairs without stack arguments. if (LeftStackArguments == nullptr) @@ -106,11 +110,11 @@ int main(int Argc, char *Argv[]) { // If IDs differ - replace the ID. if (LeftStackArguments->ID != RightStackArguments->ID) { - model::TypePath FromPath = Right->StackArgumentsType; + model::TypePath FromPath = Right->StackArgumentsType.UnqualifiedType; RightModel->Model->Types.erase(LeftStackArguments->key()); auto *Struct = llvm::dyn_cast(RightStackArguments); - revng_assert(Struct != nullptr); + revng_check(Struct != nullptr); auto Copy = model::UpcastableType::make(*Struct); Copy->ID = LeftStackArguments->ID; auto ToPath = RightModel->Model->recordNewType(std::move(Copy));