From 02b51a133a474dce8c057bc3ecea7a488587cda6 Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Tue, 14 Apr 2020 20:51:36 +0200 Subject: [PATCH] Second attempt at getting inheritance right --- test/tools/ossfuzz/SolProtoAdaptor.cpp | 466 +++++++++++++++---------- test/tools/ossfuzz/SolProtoAdaptor.h | 156 ++++++++- test/tools/ossfuzz/protoToSol.cpp | 8 +- 3 files changed, 436 insertions(+), 194 deletions(-) diff --git a/test/tools/ossfuzz/SolProtoAdaptor.cpp b/test/tools/ossfuzz/SolProtoAdaptor.cpp index 44f0a7007..d0417fe6c 100644 --- a/test/tools/ossfuzz/SolProtoAdaptor.cpp +++ b/test/tools/ossfuzz/SolProtoAdaptor.cpp @@ -137,34 +137,100 @@ string libraryFunctionMutability(SolLibraryFunctionStateMutability _mut) } } +void SolInterfaceFunction::markExplicitOverride(string _newBaseName) +{ + m_type = Type::EXPLICITOVERRIDE; + m_baseNames.clear(); + m_baseNames.push_back(_newBaseName); +} + SolInterfaceFunction::SolInterfaceFunction( - std::string _functionName, - SolFunctionStateMutability _mutability + string _functionName, + SolFunctionStateMutability _mutability, + Type _type, + string _baseName ) { m_functionName = _functionName; m_mutability = _mutability; + m_type = _type; + m_baseNames.push_back(_baseName); } -bool SolInterfaceFunction::operator==(SolInterfaceFunction const& _rhs) const +bool SolInterfaceFunction::namesake(SolInterfaceFunction const& _rhs) const { // TODO: Change this once we permit arbitrary function parameter types return name() == _rhs.name(); } +bool SolInterfaceFunction::operator==(SolInterfaceFunction const& _rhs) const +{ + solAssert(namesake(_rhs), "Sol proto adaptor: Cannot compare two interface functions with different names"); + return m_mutability == _rhs.m_mutability; +} + bool SolInterfaceFunction::operator!=(SolInterfaceFunction const& _rhs) const +{ + solAssert(namesake(_rhs), "Sol proto adaptor: Cannot compare two interface functions with different names"); + return m_mutability != _rhs.m_mutability; +} + +void SolInterfaceFunction::merge(SolInterfaceFunction const& _rhs) +{ + assertThrow( + this->operator==(_rhs), + langutil::FuzzerError, + "Sol proto adaptor: Invalid inheritance hierarchy" + ); + m_type = Type::EXPLICITOVERRIDE; + for (auto &b: _rhs.m_baseNames) + m_baseNames.push_back(b); +} + +bool SolInterfaceFunction::operator==(SolContractFunction const& _rhs) const +{ + // TODO: Change this once we permit arbitrary function parameter types + return name() == _rhs.name(); +} + +bool SolInterfaceFunction::operator!=(SolContractFunction const& _rhs) const { // TODO: Change this once we permit arbitrary function parameter types return name() != _rhs.name(); } +string SolInterfaceFunction::baseNames() const +{ + ostringstream nameStr; + string separator{}; + for (auto &b: m_baseNames) + { + nameStr << separator << b; + if (separator.empty()) + separator = ", "; + } + return nameStr.str(); +} + string SolInterfaceFunction::str() const { - return Whiskers(R"( - function () external returns (uint);)") + if (explicitOverride()) + return Whiskers(R"( + function () override() + external returns (uint);)") ("functionName", name()) + ("isMultiple", multipleBases()) + ("baseNames", baseNames()) ("stateMutability", functionMutability(mutability())) .render(); + else if (memberFunction()) + return Whiskers(R"( + function () external returns (uint);)") + ("functionName", name()) + ("stateMutability", functionMutability(mutability())) + .render(); + else + return ""; } SolContractFunction::SolContractFunction( @@ -199,6 +265,20 @@ bool SolContractFunction::operator!=(SolContractFunction const& _rhs) const return name() != _rhs.name(); } +bool SolContractFunction::operator==(SolInterfaceFunction const& _rhs) const +{ + // TODO: Consider function parameters in addition to name once they are + // implemented. + return name() == _rhs.name(); +} + +bool SolContractFunction::operator!=(SolInterfaceFunction const& _rhs) const +{ + // TODO: Consider function parameters in addition to name once they are + // implemented. + return name() != _rhs.name(); +} + bool SolContractFunction::disallowed() const { // Private virtual functions are disallowed @@ -269,6 +349,7 @@ string SolLibraryFunction::str() const .render(); } +#if 0 unsigned SolBaseContract::functionIndex() { if (type() == BaseType::INTERFACE) @@ -343,123 +424,102 @@ SolBaseContract::SolBaseContract( } } -void SolInterface::overrideHelper( - shared_ptr _function, - shared_ptr _base -) +void InterfaceFunctionAttributes::merge(InterfaceFunctionAttributes const& _rhs) { - auto functionName = _function->name(); - auto mutability = _function->mutability(); - // Check if two or more bases define this function - bool multipleOverride = false; - // If function has already been overridden, add - // new base to list of overridden bases - for (auto &m: m_overrideMap) - { - // Must override if two or more bases define the - // same function - if (m.first->operator==(*_function)) - { - // Report error if state mutability of identically - // named functions differ - if (m.first->mutability() != mutability) - assertThrow( - false, - langutil::FuzzerError, - "Input specifies multiple function overrides with identical names" - " and parameter types but different mutability." - ); -#if 1 - cout << "Overriding interface function " << - _function->name() << - " explicitly inherited from " << - _base->name() << - " by " << - name() << - endl; -#endif - - // Add new base to list of overridden bases - m_overrideMap[m.first].push_back( - shared_ptr( - make_shared( - IFunctionOverride( - _base, - _function, - this, - false, - false, - true, - "" - ) - ) - ) - ); - multipleOverride = true; - break; - } - } - // Use a pseudo-random coin flip to decide whether to override explicitly - // or not. Implicit override means that the overridden function is not - // redeclared with the override keyword. - bool explicitOverride = coinToss(); -#if 1 - if (explicitOverride) - cout << "Overriding interface function " << - _function->name() << - " explicitly inherited from " << - _base->name() << - " by " << - name() << - endl; -#endif - - // If function has not been overridden, add new override pseudo-randomly - if (!multipleOverride) - m_overrideMap.insert( - pair( - _function, - vector>{ - make_shared( - IFunctionOverride( - _base, - _function, - this, - false, - false, - explicitOverride, - "" - ) - ) - } - ) - ); + solAssert(namesake(_rhs), "Sol proto adaptor: Merge called on differently named interface functions"); + assertThrow( + this->operator==(_rhs), + langutil::FuzzerError, + "Sol proto adaptor: Invalid interface inheritance hierarchy" + ); + // Must override + m_override = true; + for (auto &b: _rhs.m_baseNames) + m_baseNames.push_back(b); } -void SolInterface::addOverrides() +bool InterfaceFunctionAttributes::namesake(InterfaceFunctionAttributes const& _rhs) const { + return m_name == _rhs.m_name; +} + +bool InterfaceFunctionAttributes::operator==(InterfaceFunctionAttributes const& _rhs) const +{ + return namesake(_rhs) && (m_mutability == _rhs.m_mutability); +} + +bool InterfaceFunctionAttributes::operator!=(InterfaceFunctionAttributes const& _rhs) const +{ + return !namesake(_rhs) || (m_mutability != _rhs.m_mutability); +} +#endif + +void SolInterface::merge() +{ + /* Merge algorithm: + * 1. Deep copy all base interface functions (local) into a single list (global) + * 2. Mark all of these as implicit overrides + * 3. Iterate list of implicit overrides + * 3a. If 2-way merge is necessary, do so and mark a two-base explicit override and add to contract + * 3b. If 2-way merge is not possible, add as implicit override to contract + * 4. Iterate list of contract implicit and explicit (2-way) overrides + * 4a. If implicit, pseudo randomly mark it explicit + */ + vector> global{}; for (auto &base: m_baseInterfaces) { - // Override base interface functions - for (auto &f: base->m_interfaceFunctions) - overrideHelper(f, base); - // Override base interface functions that are themselves overrides - for (auto &e: base->m_overrideMap) + std::cout << "Serializing " << base->name() << " functions" << std::endl; + + vector> local{}; + for (auto &bf: base->m_functions) { - solAssert(e.second.size() >= 1, "Sol proto fuzzer: Inconsistent interface override map"); - if (e.second.size() == 1) - { - if (e.second[0]->explicitlyInherited()) - overrideHelper(e.first, base); - else - overrideHelper(e.first, e.second[0]->m_baseInterface); - } - else - { - overrideHelper(e.first, base); - } + std::cout << "Adding " << bf->name() << std::endl; + local.push_back(make_shared(*bf)); + } + for (auto &l: local) + { + // Mark all as implicit overrides + l->markImplicitOverride(); + global.push_back(l); } } + + std::cout << "Unmerged global now contains " << global.size() << " functions" << std::endl; + /* + * Global has 3 + * overrides is empty + * add one implicit + * add two implicit checking if it clashes with one + * add three implicit checking if it clashes with one and two + */ + + + for (auto &f: global) + { + bool merged = false; + for (auto &e: m_functions) + { + if (e->namesake(*f)) + { + std::cout << "Performing 2-way merge of " << f->name() << std::endl; + e->merge(*f); + merged = true; + break; + } + } + if (!merged) + { + std::cout << "Implicitly overriding " << f->name() << std::endl; + m_functions.push_back(f); + } + } + std::cout << "Contract has " << m_functions.size() << " functions" << std::endl; + for (auto &e: m_functions) + if (e->implicitOverride() && coinToss()) + { + std::cout << "Explicitly overriding " << e->name() << std::endl; + e->markExplicitOverride(name()); + } } void SolInterface::addBases(Interface const& _interface) @@ -474,16 +534,19 @@ void SolInterface::addBases(Interface const& _interface) m_functionIndex += base->functionIndex(); m_lastBaseName = base->lastBaseName(); } + merge(); } void SolInterface::addFunctions(Interface const& _interface) { for (auto &f: _interface.funcdef()) - m_interfaceFunctions.push_back( + m_functions.push_back( make_shared( SolInterfaceFunction( newFunctionName(), - mutabilityConverter(f.mut()) + mutabilityConverter(f.mut()), + SolInterfaceFunction::Type::MEMBERFUNCTION, + name() ) ) ); @@ -499,7 +562,6 @@ SolInterface::SolInterface( m_interfaceName = _name; m_lastBaseName = m_interfaceName; addBases(_interface); - addOverrides(); addFunctions(_interface); } @@ -525,79 +587,88 @@ string SolInterface::baseInterfaceStr() const return baseInterfaces.str(); } -string SolInterface::overrideStr() const +string SolInterface::functionStr() const { - ostringstream overriddenFunctions; - for (auto &f: m_overrideMap) - { - ostringstream overriddenBaseNames; - if (f.second.size() > 1) - { - string sep{}; - for (auto &b: f.second) - { - overriddenBaseNames << Whiskers(R"()") - ("sep", sep) - ("name", b->baseName()) - .render(); - if (sep.empty()) - sep = ", "; - } - } - else - { - solAssert(f.second.size() == 1, "Inconsistent override map"); - if (!f.second[0]->explicitlyInherited()) - continue; - } - overriddenFunctions << Whiskers(R"( - function () external override() returns (uint);)") - ("functionName", f.first->name()) - ("stateMutability", functionMutability(f.first->mutability())) - ("multiple", f.second.size() > 1) - ("baseNames", overriddenBaseNames.str()) - .render(); - } - return overriddenFunctions.str(); + ostringstream functions; + + for (auto &f: m_functions) + functions << f->str(); + return functions.str(); } string SolInterface::str() const { - ostringstream functions; - ostringstream bases; - - // Print overridden functions - functions << overrideStr(); - // Print non-overridden functions - for (auto &f: m_interfaceFunctions) - functions << f->str(); - - for (auto &b: m_baseInterfaces) - bases << b->str(); - return Whiskers(R"( interface is { })") - ("bases", bases.str()) + ("bases", baseInterfaceStr()) ("programName", name()) - ("inheritance", m_baseInterfaces.size() > 0) + ("inheritance", bases()) ("baseNames", baseNames()) - ("functionDefs", functions.str()) + ("functionDefs", functionStr()) .render(); } +#if 0 +SolFunction::Type SolFunction::operator()(FunctionVariant _var) const +{ + if (holds_alternative>(_var)) + return SolFunction::Type::INTERFACE; + else + { + solAssert(holds_alternative>(_var), "Sol proto adaptor: Invalid Sol function"); + return SolFunction::Type::CONTRACT; + } +} + +bool ContractFunctionAttributes::namesake(ContractFunctionAttributes const& _attr) const +{ + return m_name == _attr.m_name; +} + +bool ContractFunctionAttributes::operator==(ContractFunctionAttributes const& _rhs) const +{ + return m_mutability == _rhs.m_mutability && m_visibility == _rhs.m_visibility; +} + +bool ContractFunctionAttributes::operator!=(ContractFunctionAttributes const& _rhs) const +{ + return m_mutability != _rhs.m_mutability || m_visibility != _rhs.m_visibility; +} + +void ContractFunctionAttributes::merge(ContractFunctionAttributes const& _rhs) +{ + assertThrow( + namesake(_rhs), + langutil::FuzzerError, + "Sol proto adaptor: Differently named functions cannot be merged" + ); + assertThrow( + this->operator==(_rhs), + langutil::FuzzerError, + "Sol proto adaptor: Namesake functions with different visibility and/or state mutability cannot be merged" + ); + // Must override since more than one inherited bases defines + // identical function with identical visibility and/or state + // mutability. + m_override = true; + // Add base to override base list + for (auto &b: _rhs.m_bases) + m_bases.push_back(b); +} + void SolContract::disallowedBase(shared_ptr _base1, shared_ptr _base2) { auto base1Type = _base1->type(); auto base2Type = _base2->type(); if (base1Type == SolBaseContract::BaseType::INTERFACE && base2Type == SolBaseContract::BaseType::INTERFACE) { - for (auto &bf: _base1->interface()->m_interfaceFunctions) - for (auto &lbf: _base2->interface()->m_interfaceFunctions) + for (auto &bf: _base1->interface()->m_functions) + for (auto &lbf: _base2->interface()->m_functions) assertThrow( - bf != lbf, + (bf != lbf) || (bf->mutability() == lbf->mutability()), langutil::FuzzerError, "Sol proto adaptor: New base defines namesake function with different " "visibility and/or state mutability" @@ -605,10 +676,10 @@ void SolContract::disallowedBase(shared_ptr _base1, shared_ptr< } else if (base1Type == SolBaseContract::BaseType::INTERFACE && base2Type == SolBaseContract::BaseType::CONTRACT) { - for (auto &bf: _base1->interface()->m_interfaceFunctions) + for (auto &bf: _base1->interface()->m_functions) for (auto &lbf: _base2->contract()->m_contractFunctions) - if (bf->name() == lbf->name() && - ((bf->mutability() != lbf->mutability()) || (lbf->visibility() != SolFunctionVisibility::EXTERNAL))) + if (bf != lbf || + ((bf->mutability() == lbf->mutability()) && (lbf->visibility() == SolFunctionVisibility::EXTERNAL))) assertThrow( false, langutil::FuzzerError, @@ -619,9 +690,9 @@ void SolContract::disallowedBase(shared_ptr _base1, shared_ptr< else if (base1Type == SolBaseContract::BaseType::CONTRACT && base2Type == SolBaseContract::BaseType::INTERFACE) { for (auto &bf: _base1->contract()->m_contractFunctions) - for (auto &lbf: _base2->interface()->m_interfaceFunctions) - if (bf->name() == lbf->name() && - ((bf->mutability() != lbf->mutability()) || (bf->visibility() != SolFunctionVisibility::EXTERNAL))) + for (auto &lbf: _base2->interface()->m_functions) + if (bf->name() != lbf->name() || + ((bf->mutability() == lbf->mutability()) || (bf->visibility() == SolFunctionVisibility::EXTERNAL))) assertThrow( false, langutil::FuzzerError, @@ -634,7 +705,7 @@ void SolContract::disallowedBase(shared_ptr _base1, shared_ptr< for (auto &bf: _base1->contract()->m_contractFunctions) for (auto &lbf: _base2->contract()->m_contractFunctions) assertThrow( - bf != lbf, + bf != lbf || (bf->mutability() == lbf->mutability() && bf->visibility() == lbf->visibility()), langutil::FuzzerError, "Sol proto adaptor: New base defines namesake function with different " "visibility and/or state mutability" @@ -726,8 +797,10 @@ void SolContract::interfaceFunctionOverride( bool multipleOverride = false; // If function has already been overridden, add // new base to list of overridden bases - for (auto &m: m_overriddenInterfaceFunctions) + for (auto &m: m_overriddenFunctions) { + if (holds_alternative>(m.first)) + // Must override if two or more bases define the // same function if (m.first->operator==(*_function)) @@ -790,12 +863,12 @@ void SolContract::interfaceFunctionOverride( virtualize = true; if (!multipleOverride) { - m_overriddenInterfaceFunctions.insert( + m_overriddenFunctions.insert( pair( _function, - vector>{ - make_shared( - IFunctionOverride( + vector>{ + make_shared( + CFunctionOverride( _base, _function, this, @@ -932,6 +1005,30 @@ void SolContract::contractFunctionOverride( } } +void SolContract::merge(shared_ptr _interface) +{ + /* If abstract contract, we may override interface functions + * If non abstract contract, we must override them + */ + if (m_abstract) + { + for (_interface->m_) + } + else + { + + } + +} + +void SolContract::merge(shared_ptr _base) +{ + if (_base->type() == SolBaseContract::INTERFACE) + merge(_base->interface()); + else + merge(_base->contract()); +} + void SolContract::addOverrides() { for (auto &base: m_baseContracts) @@ -940,7 +1037,7 @@ void SolContract::addOverrides() if (base->type() == SolBaseContract::BaseType::INTERFACE) { // Override interface functions - for (auto &f: base->interface()->m_interfaceFunctions) + for (auto &f: base->interface()->m_functions) { interfaceFunctionOverride(base->interface(), f); } @@ -989,8 +1086,10 @@ void SolContract::addOverrides() std::cout << "Overriding " << m.first->name() << " from " << name() << std::endl; if (m.second.size() == 1) { - if (!m.second[0]->explicitlyInherited() || (m.second[0]->virtualized() && !m.second[0]->implemented())) + if (!m.second[0]->explicitlyInherited()) interfaceFunctionOverride(m.second[0]->m_baseInterface, m.first); +// else if (m.second[0]->virtualized() && !m.second[0]->implemented()) +// interfaceFunctionOverride(base, m.first); } } } @@ -1244,6 +1343,7 @@ SolContract::SolContract( addOverrides(); addFunctions(_contract); } +#endif void SolLibrary::addFunction(LibraryFunction const& _function) { @@ -1320,6 +1420,7 @@ pair SolLibrary::pseudoRandomTest() return pair(chosenFunction, m_publicFunctionMap[chosenFunction]); } +#if 0 string CFunctionOverride::name() const { return m_baseFunction->name(); @@ -1455,4 +1556,5 @@ string IFunctionOverride::contractStr() const ("isImplemented", implemented()) ("body", bodyStr) .render(); -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/test/tools/ossfuzz/SolProtoAdaptor.h b/test/tools/ossfuzz/SolProtoAdaptor.h index 87340be8e..cc737a815 100644 --- a/test/tools/ossfuzz/SolProtoAdaptor.h +++ b/test/tools/ossfuzz/SolProtoAdaptor.h @@ -88,12 +88,29 @@ enum class SolLibraryFunctionStateMutability struct SolInterfaceFunction { + enum class Type + { + MEMBERFUNCTION, + IMPLICITOVERRIDE, + EXPLICITOVERRIDE + }; + SolInterfaceFunction( std::string _functionName, - SolFunctionStateMutability _mutability + SolFunctionStateMutability _mutability, + Type _type, + std::string _baseName ); bool operator==(SolInterfaceFunction const& _rhs) const; bool operator!=(SolInterfaceFunction const& _rhs) const; + bool operator==(SolContractFunction const& _rhs) const; + bool operator!=(SolContractFunction const& _rhs) const; + void merge(SolInterfaceFunction const& _rhs); + bool namesake(SolInterfaceFunction const& _rhs) const; + void markExplicitOverride(std::string _newBaseName); + + std::string baseNames() const; + std::string str() const; std::string name() const @@ -104,9 +121,31 @@ struct SolInterfaceFunction { return m_mutability; } + bool explicitOverride() const + { + return m_type == Type::EXPLICITOVERRIDE; + } + bool implicitOverride() const + { + return m_type == Type::IMPLICITOVERRIDE; + } + bool memberFunction() const + { + return m_type == Type::MEMBERFUNCTION; + } + void markImplicitOverride() + { + m_type = Type::IMPLICITOVERRIDE; + } + bool multipleBases() const + { + return m_baseNames.size() > 1; + } std::string m_functionName; SolFunctionStateMutability m_mutability = SolFunctionStateMutability::PURE; + std::vector m_baseNames; + Type m_type; }; struct SolContractFunction @@ -120,6 +159,8 @@ struct SolContractFunction ); bool operator==(SolContractFunction const& _rhs) const; bool operator!=(SolContractFunction const& _rhs) const; + bool operator==(SolInterfaceFunction const& _rhs) const; + bool operator!=(SolInterfaceFunction const& _rhs) const; bool disallowed() const; std::string str() const; @@ -275,6 +316,54 @@ struct SolBaseContract std::shared_ptr m_prng; }; +struct SolFunction +{ + enum Type + { + INTERFACE, + CONTRACT + }; + using FunctionVariant = std::variant, std::shared_ptr>; + + Type operator()(FunctionVariant _var) const; +}; + +struct ContractFunctionAttributes +{ + ContractFunctionAttributes( + std::variant, std::shared_ptr> _solFunction + ) + { + if (SolFunction{}(_solFunction) == SolFunction::INTERFACE) + { + auto f = std::get>(_solFunction); + m_name = f->name(); + m_mutability = f->mutability(); + m_visibility = SolFunctionVisibility::EXTERNAL; + } + else + { + auto f = std::get>(_solFunction); + m_name = f->name(); + m_mutability = f->mutability(); + m_visibility = f->visibility(); + } + } + bool namesake(ContractFunctionAttributes const& _rhs) const; + bool operator==(ContractFunctionAttributes const& _rhs) const; + bool operator!=(ContractFunctionAttributes const& _rhs) const; + void merge(ContractFunctionAttributes const& _rhs); + + std::string m_name; + SolFunctionVisibility m_visibility; + SolFunctionStateMutability m_mutability; + std::string m_returnValue; + bool m_virtual; + bool m_override; + bool m_implemeted; + std::vector m_bases; +}; + struct SolContract { SolContract( @@ -283,6 +372,10 @@ struct SolContract std::shared_ptr _prng ); + void merge(std::shared_ptr _base); + void merge(std::shared_ptr _interface); + void merge(std::shared_ptr _contract); + std::string str(); std::string interfaceOverrideStr(); std::string contractOverrideStr(); @@ -350,12 +443,41 @@ struct SolContract std::string m_lastBaseName; std::vector> m_contractFunctions; std::vector> m_baseContracts; - std::map, std::vector>> m_overriddenContractFunctions; - std::map, std::vector>> m_overriddenInterfaceFunctions; + std::map, std::shared_ptr>, + std::vector>> m_overriddenFunctions; /// Maps non abstract contract name to list of publicly exposed function name /// and their expected output std::map> m_contractFunctionMap; std::shared_ptr m_prng; + std::vector m_functions; + + +}; + +struct InterfaceFunctionAttributes +{ + InterfaceFunctionAttributes( + std::shared_ptr _function, + bool _override, + std::string _baseName + ) + { + m_name = _function->name(); + m_mutability = _function->mutability(); + m_override = _override; + m_baseNames.push_back(_baseName); + } + InterfaceFunctionAttributes(InterfaceFunctionAttributes const& _rhs); + + void merge(InterfaceFunctionAttributes const& _rhs); + bool namesake(InterfaceFunctionAttributes const& _rhs) const; + bool operator==(InterfaceFunctionAttributes const& _rhs) const; + bool operator!=(InterfaceFunctionAttributes const& _rhs) const; + + SolFunctionStateMutability m_mutability; + std::string m_name; + bool m_override = false; + std::vector m_baseNames; }; struct SolInterface @@ -366,6 +488,8 @@ struct SolInterface std::shared_ptr _prng ); + void merge(); + std::string name() const { return m_interfaceName; @@ -385,38 +509,50 @@ struct SolInterface { return "f" + std::to_string(m_functionIndex++); } + void incrementFunctionIndex() { m_functionIndex++; } + void resetFunctionIndex() { m_functionIndex = 0; } + void setFunctionIndex(unsigned _index) { m_functionIndex = _index; } + unsigned functionIndex() const { return m_functionIndex; } + std::string newBaseName() { m_lastBaseName += "B"; return m_lastBaseName; } + std::string lastBaseName() { return m_lastBaseName; } std::string str() const; + std::string overrideStr() const; /// Returns the Solidity code for all base interfaces /// inherited by this interface. std::string baseInterfaceStr() const; + std::string functionStr() const; + bool bases() const + { + return m_baseInterfaces.size() > 0; + } /// Returns comma-space separated names of base interfaces inherited by /// this interface. @@ -437,7 +573,7 @@ struct SolInterface unsigned m_functionIndex = 0; std::string m_lastBaseName; std::string m_interfaceName; - std::vector> m_interfaceFunctions; + std::vector> m_functions; std::vector> m_baseInterfaces; std::map, std::vector>> m_overrideMap; std::shared_ptr m_prng; @@ -459,7 +595,7 @@ struct CFunctionOverride }; CFunctionOverride( - std::shared_ptr _base, + std::variant, std::shared_ptr> _base, std::shared_ptr _function, SolContract* _derived, bool _implemented, @@ -492,17 +628,17 @@ struct CFunctionOverride std::string baseName() const; - std::shared_ptr baseContract() const - { - return m_baseContract; - } +// std::shared_ptr baseContract() const +// { +// return m_baseContract; +// } std::shared_ptr baseFunction() const { return m_baseFunction; } - std::shared_ptr m_baseContract; + std::variant, std::shared_ptr> m_baseContract; std::shared_ptr m_baseFunction; SolContract* m_derivedProgram; diff --git a/test/tools/ossfuzz/protoToSol.cpp b/test/tools/ossfuzz/protoToSol.cpp index 594ebd393..49ee42687 100644 --- a/test/tools/ossfuzz/protoToSol.cpp +++ b/test/tools/ossfuzz/protoToSol.cpp @@ -141,7 +141,8 @@ string ProtoConverter::visit(ContractType const& _contractType) switch (_contractType.contract_type_oneof_case()) { case ContractType::kC: - return visit(_contractType.c()); +// return visit(_contractType.c()); + return ""; case ContractType::kL: return visit(_contractType.l()); case ContractType::kI: @@ -151,8 +152,9 @@ string ProtoConverter::visit(ContractType const& _contractType) } } -string ProtoConverter::visit(Contract const& _contract) +string ProtoConverter::visit(Contract const&) { +#if 0 if (_contract.funcdef_size() == 0 && _contract.bases_size() == 0) return ""; @@ -178,6 +180,8 @@ string ProtoConverter::visit(Contract const& _contract) // Return empty string if input specification is invalid. return ""; } +#endif + return ""; } string ProtoConverter::visit(Interface const& _interface)