mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add function output params
This commit is contained in:
parent
49bdc1571e
commit
ef29a5e287
@ -222,6 +222,47 @@ string ContractGenerator::visit()
|
|||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string FunctionType::toString()
|
||||||
|
{
|
||||||
|
auto typeString = [](std::vector<SolidityTypePtr>& _types)
|
||||||
|
{
|
||||||
|
std::string sep;
|
||||||
|
std::string typeStr;
|
||||||
|
for (auto const& i: _types)
|
||||||
|
{
|
||||||
|
typeStr += sep + std::visit(GenericVisitor{
|
||||||
|
[&](auto const& _item) { return _item->toString(); }
|
||||||
|
}, i);
|
||||||
|
if (sep.empty())
|
||||||
|
sep = ",";
|
||||||
|
}
|
||||||
|
return typeStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string retString = std::string("function ") + "(" + typeString(inputs) + ")";
|
||||||
|
if (outputs.empty())
|
||||||
|
return retString + " external pure";
|
||||||
|
else
|
||||||
|
return retString + " external pure returns (" + typeString(outputs) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
string FunctionState::params(Params _p)
|
||||||
|
{
|
||||||
|
vector<string> params = (_p == Params::INPUT ? inputs : outputs) |
|
||||||
|
ranges::views::transform(
|
||||||
|
[](auto& _item) -> string
|
||||||
|
{
|
||||||
|
return visit(
|
||||||
|
GenericVisitor{[](auto const& _item) {
|
||||||
|
return _item->toString();
|
||||||
|
}}, _item.first) +
|
||||||
|
" " +
|
||||||
|
_item.second;
|
||||||
|
}) |
|
||||||
|
ranges::to<vector<string>>();
|
||||||
|
return "(" + boost::algorithm::join(params, ",") + ")";
|
||||||
|
}
|
||||||
|
|
||||||
string FunctionGenerator::visit()
|
string FunctionGenerator::visit()
|
||||||
{
|
{
|
||||||
string visibility;
|
string visibility;
|
||||||
@ -230,16 +271,47 @@ string FunctionGenerator::visit()
|
|||||||
if (!m_freeFunction)
|
if (!m_freeFunction)
|
||||||
visibility = "external";
|
visibility = "external";
|
||||||
|
|
||||||
auto inputType = TypeGenerator{state}.type();
|
// Add I/O
|
||||||
state->currentFunctionState()->addInput(pair<string, shared_ptr<SolidityType>>("i1", inputType));
|
if (uRandDist->likely(s_maxInputs + 1))
|
||||||
string inputParams = inputType->toString() + " i1";
|
for (unsigned i = 0; i < uRandDist->distributionOneToN(s_maxInputs); i++)
|
||||||
return indentation(state->indentationLevel) +
|
state->currentFunctionState()->addInput(TypeProvider{state}.type());
|
||||||
"function " + name + "(" + inputParams + ") " + visibility + " pure {}\n";
|
|
||||||
|
if (uRandDist->likely(s_maxOutputs + 1))
|
||||||
|
for (unsigned i = 0; i < uRandDist->distributionOneToN(s_maxOutputs); i++)
|
||||||
|
state->currentFunctionState()->addOutput(TypeProvider{state}.type());
|
||||||
|
|
||||||
|
ostringstream function;
|
||||||
|
function << indentation(state->indentationLevel)
|
||||||
|
<< "function "
|
||||||
|
<< name
|
||||||
|
<< state->currentFunctionState()->params(FunctionState::Params::INPUT)
|
||||||
|
<< " "
|
||||||
|
<< visibility
|
||||||
|
<< " pure"
|
||||||
|
<< " returns"
|
||||||
|
<< state->currentFunctionState()->params(FunctionState::Params::OUTPUT)
|
||||||
|
<< " {}\n";
|
||||||
|
return function.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<SolidityType> TypeGenerator::type()
|
optional<SolidityTypePtr> TypeProvider::type(SolidityTypePtr _type)
|
||||||
{
|
{
|
||||||
switch (typeCategory())
|
vector<SolidityTypePtr> matchingTypes = state->currentFunctionState()->inputs |
|
||||||
|
ranges::views::filter([&_type](auto& _item) {
|
||||||
|
return _item.first == _type;
|
||||||
|
}) |
|
||||||
|
ranges::views::transform([](auto& _item) { return _item.first; }) |
|
||||||
|
ranges::to<vector<SolidityTypePtr>>();
|
||||||
|
|
||||||
|
if (matchingTypes.empty())
|
||||||
|
return nullopt;
|
||||||
|
else
|
||||||
|
return matchingTypes[state->uRandDist->distributionOneToN(matchingTypes.size()) - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
SolidityTypePtr TypeProvider::type()
|
||||||
|
{
|
||||||
|
switch (randomTypeCategory())
|
||||||
{
|
{
|
||||||
case Type::INTEGER:
|
case Type::INTEGER:
|
||||||
{
|
{
|
||||||
@ -250,10 +322,10 @@ shared_ptr<SolidityType> TypeGenerator::type()
|
|||||||
);
|
);
|
||||||
// Choose signed/unsigned type with probability of 1/2 = 0.5
|
// Choose signed/unsigned type with probability of 1/2 = 0.5
|
||||||
bool signedType = state->uRandDist->probable(2);
|
bool signedType = state->uRandDist->probable(2);
|
||||||
return dynamic_pointer_cast<SolidityType>(make_shared<IntegerType>(b, signedType));
|
return make_shared<IntegerType>(b, signedType);
|
||||||
}
|
}
|
||||||
case Type::BOOL:
|
case Type::BOOL:
|
||||||
return dynamic_pointer_cast<SolidityType>(make_shared<BoolType>());
|
return make_shared<BoolType>();
|
||||||
case Type::FIXEDBYTES:
|
case Type::FIXEDBYTES:
|
||||||
{
|
{
|
||||||
FixedBytesType::Bytes w = static_cast<FixedBytesType::Bytes>(
|
FixedBytesType::Bytes w = static_cast<FixedBytesType::Bytes>(
|
||||||
@ -261,18 +333,18 @@ shared_ptr<SolidityType> TypeGenerator::type()
|
|||||||
static_cast<size_t>(FixedBytesType::Bytes::W32)
|
static_cast<size_t>(FixedBytesType::Bytes::W32)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
return dynamic_pointer_cast<SolidityType>(make_shared<FixedBytesType>(w));
|
return make_shared<FixedBytesType>(w);
|
||||||
}
|
}
|
||||||
case Type::BYTES:
|
case Type::BYTES:
|
||||||
return dynamic_pointer_cast<SolidityType>(make_shared<BytesType>());
|
return make_shared<BytesType>();
|
||||||
case Type::ADDRESS:
|
case Type::ADDRESS:
|
||||||
return dynamic_pointer_cast<SolidityType>(make_shared<AddressType>());
|
return make_shared<AddressType>();
|
||||||
case Type::FUNCTION:
|
case Type::FUNCTION:
|
||||||
return dynamic_pointer_cast<SolidityType>(make_shared<FunctionType>());
|
return make_shared<FunctionType>();
|
||||||
case Type::CONTRACT:
|
case Type::CONTRACT:
|
||||||
if (state->sourceUnitState[state->currentPath()]->contractType())
|
if (state->sourceUnitState[state->currentPath()]->contractType())
|
||||||
return state->sourceUnitState[state->currentPath()]->randomContractType();
|
return state->sourceUnitState[state->currentPath()]->randomContractType();
|
||||||
return dynamic_pointer_cast<SolidityType>(make_shared<BoolType>());
|
return make_shared<BoolType>();
|
||||||
default:
|
default:
|
||||||
solAssert(false, "");
|
solAssert(false, "");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <test/tools/ossfuzz/Generators.h>
|
#include <test/tools/ossfuzz/Generators.h>
|
||||||
|
#include <test/tools/ossfuzz/Types.h>
|
||||||
|
|
||||||
#include <liblangutil/Exceptions.h>
|
#include <liblangutil/Exceptions.h>
|
||||||
|
|
||||||
@ -31,6 +32,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
|
#include <range/v3/algorithm/all_of.hpp>
|
||||||
#include <range/v3/range/conversion.hpp>
|
#include <range/v3/range/conversion.hpp>
|
||||||
#include <range/v3/view/filter.hpp>
|
#include <range/v3/view/filter.hpp>
|
||||||
#include <range/v3/view/transform.hpp>
|
#include <range/v3/view/transform.hpp>
|
||||||
@ -42,22 +44,25 @@ class SolidityGenerator;
|
|||||||
|
|
||||||
/// Type declarations
|
/// Type declarations
|
||||||
#define SEMICOLON() ;
|
#define SEMICOLON() ;
|
||||||
#define FORWARDDECLAREGENERATORS(G) class G
|
#define FORWARDDECLARE(G) class G
|
||||||
GENERATORLIST(FORWARDDECLAREGENERATORS, SEMICOLON(), SEMICOLON())
|
GENERATORLIST(FORWARDDECLARE, SEMICOLON(), SEMICOLON())
|
||||||
#undef FORWARDDECLAREGENERATORS
|
TYPELIST(FORWARDDECLARE, SEMICOLON(), SEMICOLON())
|
||||||
|
#undef FORWARDDECLARE
|
||||||
#undef SEMICOLON
|
#undef SEMICOLON
|
||||||
|
|
||||||
#define COMMA() ,
|
#define COMMA() ,
|
||||||
using GeneratorPtr = std::variant<
|
|
||||||
#define VARIANTOFSHARED(G) std::shared_ptr<G>
|
|
||||||
GENERATORLIST(VARIANTOFSHARED, COMMA(), )
|
|
||||||
>;
|
|
||||||
#undef VARIANTOFSHARED
|
|
||||||
using Generator = std::variant<
|
using Generator = std::variant<
|
||||||
#define VARIANTOFGENERATOR(G) G
|
#define VARIANTOFGENERATOR(G) G
|
||||||
GENERATORLIST(VARIANTOFGENERATOR, COMMA(), )
|
GENERATORLIST(VARIANTOFGENERATOR, COMMA(), )
|
||||||
>;
|
>;
|
||||||
#undef VARIANTOFGENERATOR
|
using GeneratorPtr = std::variant<
|
||||||
|
#define VARIANTOFSHARED(G) std::shared_ptr<G>
|
||||||
|
GENERATORLIST(VARIANTOFSHARED, COMMA(), )
|
||||||
|
>;
|
||||||
|
using SolidityTypePtr = std::variant<
|
||||||
|
TYPELIST(VARIANTOFSHARED, COMMA(), )
|
||||||
|
>;
|
||||||
|
#undef VARIANTOFSHARED
|
||||||
#undef COMMA
|
#undef COMMA
|
||||||
using RandomEngine = std::mt19937_64;
|
using RandomEngine = std::mt19937_64;
|
||||||
using Distribution = std::uniform_int_distribution<size_t>;
|
using Distribution = std::uniform_int_distribution<size_t>;
|
||||||
@ -116,14 +121,16 @@ struct ContractState
|
|||||||
std::shared_ptr<UniformRandomDistribution> uRandDist;
|
std::shared_ptr<UniformRandomDistribution> uRandDist;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SolidityType
|
class SolType
|
||||||
{
|
{
|
||||||
virtual ~SolidityType() = default;
|
public:
|
||||||
|
virtual ~SolType() = default;
|
||||||
virtual std::string toString() = 0;
|
virtual std::string toString() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IntegerType: SolidityType
|
class IntegerType: public SolType
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
enum class Bits: size_t
|
enum class Bits: size_t
|
||||||
{
|
{
|
||||||
B8 = 1,
|
B8 = 1,
|
||||||
@ -167,6 +174,11 @@ struct IntegerType: SolidityType
|
|||||||
signedType(_signed),
|
signedType(_signed),
|
||||||
numBits(static_cast<size_t>(_bits) * 8)
|
numBits(static_cast<size_t>(_bits) * 8)
|
||||||
{}
|
{}
|
||||||
|
bool operator==(IntegerType const& _rhs)
|
||||||
|
{
|
||||||
|
return this->signedType == _rhs.signedType &&
|
||||||
|
this->numBits == _rhs.numBits;
|
||||||
|
}
|
||||||
std::string toString() override
|
std::string toString() override
|
||||||
{
|
{
|
||||||
return (signedType ? "int" : "uint") + std::to_string(numBits);
|
return (signedType ? "int" : "uint") + std::to_string(numBits);
|
||||||
@ -175,25 +187,36 @@ struct IntegerType: SolidityType
|
|||||||
size_t numBits;
|
size_t numBits;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BoolType: SolidityType
|
class BoolType: public SolType
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
std::string toString() override
|
std::string toString() override
|
||||||
{
|
{
|
||||||
return "bool";
|
return "bool";
|
||||||
}
|
}
|
||||||
|
bool operator==(BoolType const&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AddressType: SolidityType
|
class AddressType: public SolType
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
// TODO: Implement address payable
|
// TODO: Implement address payable
|
||||||
std::string toString() override
|
std::string toString() override
|
||||||
{
|
{
|
||||||
return "address";
|
return "address";
|
||||||
}
|
}
|
||||||
|
bool operator==(AddressType const&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FixedBytesType: SolidityType
|
class FixedBytesType: public SolType
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
enum class Bytes: size_t
|
enum class Bytes: size_t
|
||||||
{
|
{
|
||||||
W1 = 1,
|
W1 = 1,
|
||||||
@ -232,6 +255,10 @@ struct FixedBytesType: SolidityType
|
|||||||
FixedBytesType(Bytes _width): numBytes(static_cast<size_t>(_width))
|
FixedBytesType(Bytes _width): numBytes(static_cast<size_t>(_width))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
bool operator==(FixedBytesType const& _rhs)
|
||||||
|
{
|
||||||
|
return this->numBytes == _rhs.numBytes;
|
||||||
|
}
|
||||||
std::string toString() override
|
std::string toString() override
|
||||||
{
|
{
|
||||||
return "bytes" + std::to_string(numBytes);
|
return "bytes" + std::to_string(numBytes);
|
||||||
@ -239,16 +266,22 @@ struct FixedBytesType: SolidityType
|
|||||||
size_t numBytes;
|
size_t numBytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BytesType: SolidityType
|
class BytesType: public SolType
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
std::string toString() override
|
std::string toString() override
|
||||||
{
|
{
|
||||||
return "bytes memory";
|
return "bytes memory";
|
||||||
}
|
}
|
||||||
|
bool operator==(BytesType const&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ContractType: SolidityType
|
class ContractType: public SolType
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
ContractType(std::string _name): contractName(_name)
|
ContractType(std::string _name): contractName(_name)
|
||||||
{}
|
{}
|
||||||
std::string toString() override
|
std::string toString() override
|
||||||
@ -259,11 +292,16 @@ struct ContractType: SolidityType
|
|||||||
{
|
{
|
||||||
return contractName;
|
return contractName;
|
||||||
}
|
}
|
||||||
|
bool operator==(ContractType const&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
std::string contractName;
|
std::string contractName;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionType: SolidityType
|
class FunctionType: public SolType
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
FunctionType() = default;
|
FunctionType() = default;
|
||||||
~FunctionType() override
|
~FunctionType() override
|
||||||
{
|
{
|
||||||
@ -271,40 +309,30 @@ struct FunctionType: SolidityType
|
|||||||
outputs.clear();
|
outputs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addInput(std::shared_ptr<SolidityType> _input)
|
void addInput(SolidityTypePtr _input)
|
||||||
{
|
{
|
||||||
inputs.emplace_back(_input);
|
inputs.emplace_back(_input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addOutput(std::shared_ptr<SolidityType> _output)
|
void addOutput(SolidityTypePtr _output)
|
||||||
{
|
{
|
||||||
outputs.emplace_back(_output);
|
outputs.emplace_back(_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toString() override
|
std::string toString() override;
|
||||||
|
bool operator==(FunctionType const& _rhs)
|
||||||
{
|
{
|
||||||
auto typeString = [](std::vector<std::shared_ptr<SolidityType>>& _types)
|
if (_rhs.inputs.size() != this->inputs.size() || _rhs.outputs.size() != this->outputs.size())
|
||||||
{
|
return false;
|
||||||
std::string sep;
|
if (!std::equal(_rhs.inputs.begin(), _rhs.inputs.end(), this->inputs.begin()) ||
|
||||||
std::string typeStr;
|
!std::equal(_rhs.outputs.begin(), _rhs.outputs.end(), this->outputs.begin())
|
||||||
for (auto const& i: _types)
|
)
|
||||||
{
|
return false;
|
||||||
typeStr += sep + i->toString();
|
return true;
|
||||||
if (sep.empty())
|
|
||||||
sep = ",";
|
|
||||||
}
|
|
||||||
return typeStr;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string retString = std::string("function ") + "(" + typeString(inputs) + ")";
|
|
||||||
if (outputs.empty())
|
|
||||||
return retString + " external pure";
|
|
||||||
else
|
|
||||||
return retString + " external pure returns (" + typeString(outputs) + ")";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<SolidityType>> inputs;
|
std::vector<SolidityTypePtr> inputs;
|
||||||
std::vector<std::shared_ptr<SolidityType>> outputs;
|
std::vector<SolidityTypePtr> outputs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Forward declaration
|
/// Forward declaration
|
||||||
@ -318,7 +346,7 @@ struct SourceState
|
|||||||
{}
|
{}
|
||||||
void addFreeFunction(std::string& _functionName)
|
void addFreeFunction(std::string& _functionName)
|
||||||
{
|
{
|
||||||
exports[std::dynamic_pointer_cast<SolidityType>(std::make_shared<FunctionType>())] = _functionName;
|
exports[std::make_shared<FunctionType>()] = _functionName;
|
||||||
}
|
}
|
||||||
bool freeFunction(std::string const& _functionName)
|
bool freeFunction(std::string const& _functionName)
|
||||||
{
|
{
|
||||||
@ -327,37 +355,39 @@ struct SourceState
|
|||||||
bool contractType()
|
bool contractType()
|
||||||
{
|
{
|
||||||
return !(exports | ranges::views::filter([](auto& _i) {
|
return !(exports | ranges::views::filter([](auto& _i) {
|
||||||
return bool(std::dynamic_pointer_cast<ContractType>(_i.first));
|
return std::holds_alternative<std::shared_ptr<ContractType>>(_i.first);
|
||||||
})).empty();
|
})).empty();
|
||||||
}
|
}
|
||||||
std::string randomContract()
|
std::string randomContract()
|
||||||
{
|
{
|
||||||
auto contracts = exports |
|
auto contracts = exports |
|
||||||
ranges::views::filter([](auto& _item) -> bool {
|
ranges::views::filter([](auto& _item) -> bool {
|
||||||
return bool(std::dynamic_pointer_cast<ContractType>(_item.first));
|
return std::holds_alternative<std::shared_ptr<ContractType>>(
|
||||||
|
_item.first
|
||||||
|
);
|
||||||
}) |
|
}) |
|
||||||
ranges::views::transform([](auto& _item) -> std::string {
|
ranges::views::transform([](auto& _item) -> std::string {
|
||||||
return _item.second;
|
return _item.second;
|
||||||
}) | ranges::to<std::vector<std::string>>;
|
}) | ranges::to<std::vector<std::string>>;
|
||||||
return contracts[uRandDist->distributionOneToN(contracts.size()) - 1];
|
return contracts[uRandDist->distributionOneToN(contracts.size()) - 1];
|
||||||
}
|
}
|
||||||
std::shared_ptr<SolidityType> randomContractType()
|
std::shared_ptr<ContractType> randomContractType()
|
||||||
{
|
{
|
||||||
auto contracts = exports |
|
auto contracts = exports |
|
||||||
ranges::views::filter([](auto& _item) -> bool {
|
ranges::views::filter([](auto& _item) -> bool {
|
||||||
return bool(std::dynamic_pointer_cast<ContractType>(_item.first));
|
return std::holds_alternative<std::shared_ptr<ContractType>>(_item.first);
|
||||||
}) |
|
}) |
|
||||||
ranges::views::transform([](auto& _item) -> std::shared_ptr<SolidityType> {
|
ranges::views::transform([](auto& _item) -> std::shared_ptr<ContractType> {
|
||||||
return _item.first;
|
return std::get<std::shared_ptr<ContractType>>(_item.first);
|
||||||
}) |
|
}) |
|
||||||
ranges::to<std::vector<std::shared_ptr<SolidityType>>>;
|
ranges::to<std::vector<std::shared_ptr<ContractType>>>;
|
||||||
return contracts[uRandDist->distributionOneToN(contracts.size()) - 1];
|
return contracts[uRandDist->distributionOneToN(contracts.size()) - 1];
|
||||||
}
|
}
|
||||||
void addImportedSourcePath(std::string& _sourcePath)
|
void addImportedSourcePath(std::string& _sourcePath)
|
||||||
{
|
{
|
||||||
importedSources.emplace(_sourcePath);
|
importedSources.emplace(_sourcePath);
|
||||||
}
|
}
|
||||||
void resolveImports(std::map<std::shared_ptr<SolidityType>, std::string> _imports)
|
void resolveImports(std::map<SolidityTypePtr, std::string> _imports)
|
||||||
{
|
{
|
||||||
for (auto const& item: _imports)
|
for (auto const& item: _imports)
|
||||||
exports.emplace(item);
|
exports.emplace(item);
|
||||||
@ -374,28 +404,37 @@ struct SourceState
|
|||||||
void print(std::ostream& _os) const;
|
void print(std::ostream& _os) const;
|
||||||
std::shared_ptr<UniformRandomDistribution> uRandDist;
|
std::shared_ptr<UniformRandomDistribution> uRandDist;
|
||||||
std::set<std::string> importedSources;
|
std::set<std::string> importedSources;
|
||||||
std::map<std::shared_ptr<SolidityType>, std::string> exports;
|
std::map<SolidityTypePtr, std::string> exports;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionState
|
struct FunctionState
|
||||||
{
|
{
|
||||||
|
enum class Params
|
||||||
|
{
|
||||||
|
INPUT,
|
||||||
|
OUTPUT
|
||||||
|
};
|
||||||
FunctionState() = default;
|
FunctionState() = default;
|
||||||
~FunctionState()
|
~FunctionState()
|
||||||
{
|
{
|
||||||
inputs.clear();
|
inputs.clear();
|
||||||
outputs.clear();
|
outputs.clear();
|
||||||
}
|
}
|
||||||
void addInput(std::pair<std::string, std::shared_ptr<SolidityType>> _input)
|
using TypeId = std::pair<SolidityTypePtr, std::string>;
|
||||||
|
void addInput(SolidityTypePtr _input)
|
||||||
{
|
{
|
||||||
inputs.emplace(_input);
|
inputs.emplace(_input, "i" + std::to_string(numInputs++));
|
||||||
}
|
}
|
||||||
void addOutput(std::pair<std::string, std::shared_ptr<SolidityType>> _output)
|
void addOutput(SolidityTypePtr _output)
|
||||||
{
|
{
|
||||||
outputs.emplace(_output);
|
outputs.emplace(_output, "o" + std::to_string(numOutpus++));
|
||||||
}
|
}
|
||||||
|
std::string params(Params _p);
|
||||||
|
|
||||||
std::map<std::string, std::shared_ptr<SolidityType>> inputs;
|
std::map<SolidityTypePtr, std::string> inputs;
|
||||||
std::map<std::string, std::shared_ptr<SolidityType>> outputs;
|
std::map<SolidityTypePtr, std::string> outputs;
|
||||||
|
unsigned numInputs = 0;
|
||||||
|
unsigned numOutpus = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TestState
|
struct TestState
|
||||||
@ -547,9 +586,9 @@ struct TestState
|
|||||||
std::string const functionPrefix = "f";
|
std::string const functionPrefix = "f";
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeGenerator
|
struct TypeProvider
|
||||||
{
|
{
|
||||||
TypeGenerator(std::shared_ptr<TestState> _state): state(std::move(_state))
|
TypeProvider(std::shared_ptr<TestState> _state): state(std::move(_state))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
enum class Type: size_t
|
enum class Type: size_t
|
||||||
@ -564,9 +603,10 @@ struct TypeGenerator
|
|||||||
TYPEMAX
|
TYPEMAX
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<SolidityType> type();
|
SolidityTypePtr type();
|
||||||
|
std::optional<SolidityTypePtr> type(SolidityTypePtr _typePtr);
|
||||||
|
|
||||||
Type typeCategory()
|
Type randomTypeCategory()
|
||||||
{
|
{
|
||||||
return static_cast<Type>(state->uRandDist->distributionOneToN(static_cast<size_t>(Type::TYPEMAX) - 1));
|
return static_cast<Type>(state->uRandDist->distributionOneToN(static_cast<size_t>(Type::TYPEMAX) - 1));
|
||||||
}
|
}
|
||||||
@ -574,6 +614,22 @@ struct TypeGenerator
|
|||||||
std::shared_ptr<TestState> state;
|
std::shared_ptr<TestState> state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ExpressionGenerator
|
||||||
|
{
|
||||||
|
ExpressionGenerator(std::shared_ptr<TestState> _state): state(std::move(_state))
|
||||||
|
{}
|
||||||
|
|
||||||
|
enum class Expr: size_t
|
||||||
|
{
|
||||||
|
VARREF = 1,
|
||||||
|
TYPEMAX
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string expression(SolidityTypePtr _type);
|
||||||
|
|
||||||
|
std::shared_ptr<TestState> state;
|
||||||
|
};
|
||||||
|
|
||||||
struct GeneratorBase
|
struct GeneratorBase
|
||||||
{
|
{
|
||||||
explicit GeneratorBase(std::shared_ptr<SolidityGenerator> _mutator);
|
explicit GeneratorBase(std::shared_ptr<SolidityGenerator> _mutator);
|
||||||
@ -742,7 +798,8 @@ public:
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
bool m_freeFunction;
|
bool m_freeFunction;
|
||||||
|
static constexpr unsigned s_maxInputs = 4;
|
||||||
|
static constexpr unsigned s_maxOutputs = 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SolidityGenerator: public std::enable_shared_from_this<SolidityGenerator>
|
class SolidityGenerator: public std::enable_shared_from_this<SolidityGenerator>
|
||||||
|
|||||||
56
test/tools/ossfuzz/Types.h
Normal file
56
test/tools/ossfuzz/Types.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
/**
|
||||||
|
* Convenience macros for Solidity generator type declarations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Alphabetically sorted Solidity types.
|
||||||
|
* SEP must appear between two elements and ENDSEP must
|
||||||
|
* appear after the last element.
|
||||||
|
*
|
||||||
|
* This macro applies another macro (MACRO) that is
|
||||||
|
* passed as input to this macro on the list of Generator
|
||||||
|
* types. Example that uses forward declaration:
|
||||||
|
*
|
||||||
|
* #define MACRO(T) struct T;
|
||||||
|
* #define SEMICOLON() ;
|
||||||
|
*
|
||||||
|
* TYPELIST(MACRO, SEMICOLON(), SEMICOLON())
|
||||||
|
*
|
||||||
|
* produces
|
||||||
|
*
|
||||||
|
* struct PragmaGenerator;class SourceUnitGenerator;class TestCaseGenerator;
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define TYPELIST(MACRO, SEP, ENDSEP) \
|
||||||
|
MACRO(AddressType) SEP \
|
||||||
|
MACRO(BoolType) SEP \
|
||||||
|
MACRO(BytesType) SEP \
|
||||||
|
MACRO(ContractType) SEP \
|
||||||
|
MACRO(FixedBytesType) SEP \
|
||||||
|
MACRO(FunctionType) SEP \
|
||||||
|
MACRO(IntegerType) ENDSEP
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user