mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[ci skip] Add magic expressions such as keccak256/ripemd etc.
This commit is contained in:
parent
66ee8a647e
commit
3481a402d7
@ -942,30 +942,126 @@ optional<pair<SolidityTypePtr, string>> ExpressionGenerator::incDecOperation(
|
||||
return lResult;
|
||||
}
|
||||
|
||||
optional<pair<SolidityTypePtr, string>> ExpressionGenerator::memberAccessExpr(
|
||||
pair<SolidityTypePtr, string>& _typeName
|
||||
)
|
||||
pair<SolidityTypePtr, string> ExpressionGenerator::memberAccessExpr(SolidityTypePtr& _type)
|
||||
{
|
||||
solAssert(
|
||||
holds_alternative<shared_ptr<IntegerType>>(_typeName.first) ||
|
||||
holds_alternative<shared_ptr<BytesType>>(_typeName.first) ||
|
||||
holds_alternative<shared_ptr<FixedBytesType>>(_typeName.first),
|
||||
holds_alternative<shared_ptr<IntegerType>>(_type) ||
|
||||
holds_alternative<shared_ptr<BytesType>>(_type) ||
|
||||
holds_alternative<shared_ptr<FixedBytesType>>(_type),
|
||||
""
|
||||
);
|
||||
ExpressionGenerator exprGen{state};
|
||||
auto addressType = make_shared<AddressType>();
|
||||
pair<SolidityTypePtr, string> addressTypeName = {addressType, {}};
|
||||
auto expression = exprGen.rLValueOrLiteral(addressTypeName);
|
||||
exprGen.resetNestingDepth();
|
||||
auto expression = rLValueOrLiteral(addressTypeName);
|
||||
solAssert(expression.has_value(), "");
|
||||
// TODO: Clean this up
|
||||
if (holds_alternative<shared_ptr<IntegerType>>(_typeName.first))
|
||||
if (holds_alternative<shared_ptr<IntegerType>>(_type))
|
||||
expression.value().second += ".balance";
|
||||
else if (holds_alternative<shared_ptr<FixedBytesType>>(_typeName.first))
|
||||
else if (holds_alternative<shared_ptr<BytesType>>(_type))
|
||||
expression.value().second += ".codehash";
|
||||
else
|
||||
expression.value().second += ".code";
|
||||
return expression;
|
||||
return expression.value();
|
||||
}
|
||||
|
||||
pair<SolidityTypePtr, string> ExpressionGenerator::magicExpr(SolidityTypePtr& _type)
|
||||
{
|
||||
solAssert(
|
||||
holds_alternative<shared_ptr<IntegerType>>(_type) ||
|
||||
holds_alternative<shared_ptr<AddressType>>(_type) ||
|
||||
holds_alternative<shared_ptr<FixedBytesType>>(_type),
|
||||
""
|
||||
);
|
||||
if (holds_alternative<shared_ptr<IntegerType>>(_type))
|
||||
{
|
||||
auto integerType = get<shared_ptr<IntegerType>>(_type);
|
||||
solAssert(!integerType->signedType && integerType->numBits == 256, "");
|
||||
auto paramIntType = make_shared<IntegerType>(IntegerType::Bits::B256, false);
|
||||
pair<SolidityTypePtr, string> paramIntTypeName = {paramIntType, {}};
|
||||
auto x = rLValueOrLiteral(paramIntTypeName);
|
||||
auto y = rLValueOrLiteral(paramIntTypeName);
|
||||
auto k = rLValueOrLiteral(paramIntTypeName);
|
||||
solAssert(x.has_value() && y.has_value() && k.has_value(), "");
|
||||
string builtin;
|
||||
if (state->uRandDist->probable(2))
|
||||
builtin = "addmod";
|
||||
else
|
||||
builtin = "mulmod";
|
||||
auto builtinExpr = builtin +
|
||||
"(" +
|
||||
x.value().second +
|
||||
", " +
|
||||
y.value().second +
|
||||
", " +
|
||||
k.value().second +
|
||||
")";
|
||||
return pair<SolidityTypePtr, string>(paramIntType, builtinExpr);
|
||||
}
|
||||
else if (holds_alternative<shared_ptr<AddressType>>(_type))
|
||||
{
|
||||
// ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
|
||||
auto bytes32Type = make_shared<FixedBytesType>(FixedBytesType::Bytes::W32);
|
||||
auto uint8Type = make_shared<IntegerType>(IntegerType::Bits::B8, false);
|
||||
pair<SolidityTypePtr, string> paramBytes32TypeName = {bytes32Type, {}};
|
||||
pair<SolidityTypePtr, string> paramUint8TypeName = {uint8Type, {}};
|
||||
auto hash = rLValueOrLiteral(paramBytes32TypeName);
|
||||
auto r = rLValueOrLiteral(paramBytes32TypeName);
|
||||
auto s = rLValueOrLiteral(paramBytes32TypeName);
|
||||
auto v = rLValueOrLiteral(paramUint8TypeName);
|
||||
solAssert(hash.has_value() && r.has_value() && s.has_value() && v.has_value(), "");
|
||||
string builtinExpr = string("ecrecover") +
|
||||
"(" +
|
||||
hash.value().second +
|
||||
", " +
|
||||
v.value().second +
|
||||
", " +
|
||||
r.value().second +
|
||||
", " +
|
||||
s.value().second +
|
||||
")";
|
||||
auto addressType = make_shared<AddressType>();
|
||||
return pair<SolidityTypePtr, string>(addressType, builtinExpr);
|
||||
}
|
||||
else if (holds_alternative<shared_ptr<FixedBytesType>>(_type))
|
||||
{
|
||||
auto fixedBytesType = get<shared_ptr<FixedBytesType>>(_type);
|
||||
if (fixedBytesType->numBytes == 20)
|
||||
{
|
||||
// ripemd160(bytes memory) returns (bytes20)
|
||||
auto bytes20Type = make_shared<FixedBytesType>(FixedBytesType::Bytes::W20);
|
||||
auto bytesType = make_shared<BytesType>();
|
||||
pair<SolidityTypePtr, string> paramBytesTypeName = {bytesType, {}};
|
||||
auto mem = rLValueOrLiteral(paramBytesTypeName);
|
||||
solAssert(mem.has_value(), "");
|
||||
string ripemdExpr = string("ripemd160") +
|
||||
"(" +
|
||||
mem.value().second +
|
||||
")";
|
||||
return pair<SolidityTypePtr, string>(bytes20Type, ripemdExpr);
|
||||
}
|
||||
else
|
||||
{
|
||||
solAssert(fixedBytesType->numBytes == 32, "");
|
||||
auto bytes32Type = make_shared<FixedBytesType>(FixedBytesType::Bytes::W32);
|
||||
auto bytesType = make_shared<BytesType>();
|
||||
pair<SolidityTypePtr, string> paramBytesTypeName = {bytesType, {}};
|
||||
auto mem = rLValueOrLiteral(paramBytesTypeName);
|
||||
solAssert(mem.has_value(), "");
|
||||
// sha256(bytes memory) returns (bytes32)
|
||||
// keccak256(bytes memory) returns (bytes32)
|
||||
string builtin;
|
||||
if (state->uRandDist->probable(2))
|
||||
builtin = "sha256";
|
||||
else
|
||||
builtin = "keccak256";
|
||||
string builtinExpr = builtin +
|
||||
"(" +
|
||||
mem.value().second +
|
||||
")";
|
||||
return pair<SolidityTypePtr, string>(bytes32Type, builtinExpr);
|
||||
}
|
||||
}
|
||||
solAssert(false, "");
|
||||
}
|
||||
|
||||
ExpressionGenerator::RLValueExpr ExpressionGenerator::expressionType(SolidityTypePtr& _typePtr)
|
||||
@ -973,7 +1069,6 @@ ExpressionGenerator::RLValueExpr ExpressionGenerator::expressionType(SolidityTyp
|
||||
vector<RLValueExpr> permittedTypes;
|
||||
|
||||
if (holds_alternative<shared_ptr<BoolType>>(_typePtr))
|
||||
{
|
||||
permittedTypes = {
|
||||
RLValueExpr::VARREF,
|
||||
RLValueExpr::LIT,
|
||||
@ -987,7 +1082,6 @@ ExpressionGenerator::RLValueExpr ExpressionGenerator::expressionType(SolidityTyp
|
||||
RLValueExpr::AND,
|
||||
RLValueExpr::OR
|
||||
};
|
||||
}
|
||||
else if (holds_alternative<shared_ptr<FixedBytesType>>(_typePtr))
|
||||
{
|
||||
permittedTypes = {
|
||||
@ -999,7 +1093,12 @@ ExpressionGenerator::RLValueExpr ExpressionGenerator::expressionType(SolidityTyp
|
||||
};
|
||||
auto bytesType = get<shared_ptr<FixedBytesType>>(_typePtr);
|
||||
if (bytesType->numBytes == 32)
|
||||
{
|
||||
permittedTypes.emplace_back(RLValueExpr::MEMBERACCESS);
|
||||
permittedTypes.emplace_back(RLValueExpr::MAGICEXPR);
|
||||
}
|
||||
else if (bytesType->numBytes == 20)
|
||||
permittedTypes.emplace_back(RLValueExpr::MAGICEXPR);
|
||||
}
|
||||
else if (holds_alternative<shared_ptr<IntegerType>>(_typePtr))
|
||||
{
|
||||
@ -1047,21 +1146,22 @@ ExpressionGenerator::RLValueExpr ExpressionGenerator::expressionType(SolidityTyp
|
||||
RLValueExpr::BITOR
|
||||
};
|
||||
if (integerType->numBits == 256)
|
||||
{
|
||||
permittedTypes.emplace_back(RLValueExpr::MEMBERACCESS);
|
||||
permittedTypes.emplace_back(RLValueExpr::MAGICEXPR);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (holds_alternative<shared_ptr<BytesType>>(_typePtr))
|
||||
{
|
||||
permittedTypes = {
|
||||
RLValueExpr::VARREF,
|
||||
RLValueExpr::LIT,
|
||||
RLValueExpr::MEMBERACCESS
|
||||
};
|
||||
}
|
||||
else if (holds_alternative<shared_ptr<AddressType>>(_typePtr))
|
||||
permittedTypes = {RLValueExpr::VARREF, RLValueExpr::LIT, RLValueExpr::MAGICEXPR};
|
||||
else
|
||||
{
|
||||
permittedTypes = {RLValueExpr::VARREF, RLValueExpr::LIT};
|
||||
}
|
||||
return permittedTypes[state->uRandDist->distributionOneToN(permittedTypes.size()) - 1];
|
||||
}
|
||||
|
||||
@ -1369,7 +1469,9 @@ optional<pair<SolidityTypePtr, string>> ExpressionGenerator::rOrLValueExpression
|
||||
case RLValueExpr::LIT:
|
||||
return literal(_typeName.first);
|
||||
case RLValueExpr::MEMBERACCESS:
|
||||
return memberAccessExpr(_typeName);
|
||||
return memberAccessExpr(_typeName.first);
|
||||
case RLValueExpr::MAGICEXPR:
|
||||
return magicExpr(_typeName.first);
|
||||
default:
|
||||
solAssert(false, "");
|
||||
}
|
||||
@ -1459,20 +1561,120 @@ SolidityTypePtr TypeProvider::type()
|
||||
{
|
||||
switch (randomTypeCategory())
|
||||
{
|
||||
case Type::INTEGER:
|
||||
case Type::UINT8:
|
||||
case Type::UINT16:
|
||||
case Type::UINT24:
|
||||
case Type::UINT32:
|
||||
case Type::UINT40:
|
||||
case Type::UINT48:
|
||||
case Type::UINT56:
|
||||
case Type::UINT64:
|
||||
case Type::UINT72:
|
||||
case Type::UINT80:
|
||||
case Type::UINT88:
|
||||
case Type::UINT96:
|
||||
case Type::UINT104:
|
||||
case Type::UINT112:
|
||||
case Type::UINT120:
|
||||
case Type::UINT128:
|
||||
case Type::UINT136:
|
||||
case Type::UINT144:
|
||||
case Type::UINT152:
|
||||
case Type::UINT160:
|
||||
case Type::UINT168:
|
||||
case Type::UINT176:
|
||||
case Type::UINT184:
|
||||
case Type::UINT192:
|
||||
case Type::UINT200:
|
||||
case Type::UINT208:
|
||||
case Type::UINT216:
|
||||
case Type::UINT224:
|
||||
case Type::UINT232:
|
||||
case Type::UINT240:
|
||||
case Type::UINT248:
|
||||
case Type::UINT256:
|
||||
{
|
||||
IntegerType::Bits b = static_cast<IntegerType::Bits>(
|
||||
state->uRandDist->distributionOneToN(
|
||||
static_cast<size_t>(IntegerType::Bits::B256)
|
||||
)
|
||||
);
|
||||
// Choose signed/unsigned type with probability of 1/2 = 0.5
|
||||
bool signedType = state->uRandDist->probable(2);
|
||||
return make_shared<IntegerType>(b, signedType);
|
||||
return make_shared<IntegerType>(b, false);
|
||||
}
|
||||
case Type::INT8:
|
||||
case Type::INT16:
|
||||
case Type::INT24:
|
||||
case Type::INT32:
|
||||
case Type::INT40:
|
||||
case Type::INT48:
|
||||
case Type::INT56:
|
||||
case Type::INT64:
|
||||
case Type::INT72:
|
||||
case Type::INT80:
|
||||
case Type::INT88:
|
||||
case Type::INT96:
|
||||
case Type::INT104:
|
||||
case Type::INT112:
|
||||
case Type::INT120:
|
||||
case Type::INT128:
|
||||
case Type::INT136:
|
||||
case Type::INT144:
|
||||
case Type::INT152:
|
||||
case Type::INT160:
|
||||
case Type::INT168:
|
||||
case Type::INT176:
|
||||
case Type::INT184:
|
||||
case Type::INT192:
|
||||
case Type::INT200:
|
||||
case Type::INT208:
|
||||
case Type::INT216:
|
||||
case Type::INT224:
|
||||
case Type::INT232:
|
||||
case Type::INT240:
|
||||
case Type::INT248:
|
||||
case Type::INT256:
|
||||
{
|
||||
IntegerType::Bits b = static_cast<IntegerType::Bits>(
|
||||
state->uRandDist->distributionOneToN(
|
||||
static_cast<size_t>(IntegerType::Bits::B256)
|
||||
)
|
||||
);
|
||||
return make_shared<IntegerType>(b, true);
|
||||
}
|
||||
case Type::BOOL:
|
||||
return make_shared<BoolType>();
|
||||
case Type::FIXEDBYTES:
|
||||
case Type::FIXEDBYTES1:
|
||||
case Type::FIXEDBYTES2:
|
||||
case Type::FIXEDBYTES3:
|
||||
case Type::FIXEDBYTES4:
|
||||
case Type::FIXEDBYTES5:
|
||||
case Type::FIXEDBYTES6:
|
||||
case Type::FIXEDBYTES7:
|
||||
case Type::FIXEDBYTES8:
|
||||
case Type::FIXEDBYTES9:
|
||||
case Type::FIXEDBYTES10:
|
||||
case Type::FIXEDBYTES11:
|
||||
case Type::FIXEDBYTES12:
|
||||
case Type::FIXEDBYTES13:
|
||||
case Type::FIXEDBYTES14:
|
||||
case Type::FIXEDBYTES15:
|
||||
case Type::FIXEDBYTES16:
|
||||
case Type::FIXEDBYTES17:
|
||||
case Type::FIXEDBYTES18:
|
||||
case Type::FIXEDBYTES19:
|
||||
case Type::FIXEDBYTES20:
|
||||
case Type::FIXEDBYTES21:
|
||||
case Type::FIXEDBYTES22:
|
||||
case Type::FIXEDBYTES23:
|
||||
case Type::FIXEDBYTES24:
|
||||
case Type::FIXEDBYTES25:
|
||||
case Type::FIXEDBYTES26:
|
||||
case Type::FIXEDBYTES27:
|
||||
case Type::FIXEDBYTES28:
|
||||
case Type::FIXEDBYTES29:
|
||||
case Type::FIXEDBYTES30:
|
||||
case Type::FIXEDBYTES31:
|
||||
case Type::FIXEDBYTES32:
|
||||
{
|
||||
FixedBytesType::Bytes w = static_cast<FixedBytesType::Bytes>(
|
||||
state->uRandDist->distributionOneToN(
|
||||
@ -1651,11 +1853,11 @@ string FunctionCallGenerator::visit()
|
||||
string MagicStmtGenerator::visit()
|
||||
{
|
||||
MagicId m = static_cast<MagicId>(uRandDist()->distributionOneToN(static_cast<size_t>(MagicId::MAGICMAX) - 1));
|
||||
ExpressionGenerator exprGen{state};
|
||||
switch (m)
|
||||
{
|
||||
case MagicId::ASSERT:
|
||||
{
|
||||
ExpressionGenerator exprGen{state};
|
||||
auto boolType = make_shared<BoolType>();
|
||||
pair<SolidityTypePtr, string> boolTypeName = {boolType, {}};
|
||||
auto expression = exprGen.rLValueOrLiteral(boolTypeName);
|
||||
@ -1668,7 +1870,6 @@ string MagicStmtGenerator::visit()
|
||||
}
|
||||
case MagicId::REQUIRE:
|
||||
{
|
||||
ExpressionGenerator exprGen{state};
|
||||
auto boolType = make_shared<BoolType>();
|
||||
pair<SolidityTypePtr, string> boolTypeName = {boolType, {}};
|
||||
auto expression = exprGen.rLValueOrLiteral(boolTypeName);
|
||||
|
@ -721,9 +721,103 @@ struct TypeProvider
|
||||
|
||||
enum class Type: size_t
|
||||
{
|
||||
INTEGER = 1,
|
||||
UINT8 = 1,
|
||||
UINT16,
|
||||
UINT24,
|
||||
UINT32,
|
||||
UINT40,
|
||||
UINT48,
|
||||
UINT56,
|
||||
UINT64,
|
||||
UINT72,
|
||||
UINT80,
|
||||
UINT88,
|
||||
UINT96,
|
||||
UINT104,
|
||||
UINT112,
|
||||
UINT120,
|
||||
UINT128,
|
||||
UINT136,
|
||||
UINT144,
|
||||
UINT152,
|
||||
UINT160,
|
||||
UINT168,
|
||||
UINT176,
|
||||
UINT184,
|
||||
UINT192,
|
||||
UINT200,
|
||||
UINT208,
|
||||
UINT216,
|
||||
UINT224,
|
||||
UINT232,
|
||||
UINT240,
|
||||
UINT248,
|
||||
UINT256,
|
||||
INT8,
|
||||
INT16,
|
||||
INT24,
|
||||
INT32,
|
||||
INT40,
|
||||
INT48,
|
||||
INT56,
|
||||
INT64,
|
||||
INT72,
|
||||
INT80,
|
||||
INT88,
|
||||
INT96,
|
||||
INT104,
|
||||
INT112,
|
||||
INT120,
|
||||
INT128,
|
||||
INT136,
|
||||
INT144,
|
||||
INT152,
|
||||
INT160,
|
||||
INT168,
|
||||
INT176,
|
||||
INT184,
|
||||
INT192,
|
||||
INT200,
|
||||
INT208,
|
||||
INT216,
|
||||
INT224,
|
||||
INT232,
|
||||
INT240,
|
||||
INT248,
|
||||
INT256,
|
||||
BOOL,
|
||||
FIXEDBYTES,
|
||||
FIXEDBYTES1,
|
||||
FIXEDBYTES2,
|
||||
FIXEDBYTES3,
|
||||
FIXEDBYTES4,
|
||||
FIXEDBYTES5,
|
||||
FIXEDBYTES6,
|
||||
FIXEDBYTES7,
|
||||
FIXEDBYTES8,
|
||||
FIXEDBYTES9,
|
||||
FIXEDBYTES10,
|
||||
FIXEDBYTES11,
|
||||
FIXEDBYTES12,
|
||||
FIXEDBYTES13,
|
||||
FIXEDBYTES14,
|
||||
FIXEDBYTES15,
|
||||
FIXEDBYTES16,
|
||||
FIXEDBYTES17,
|
||||
FIXEDBYTES18,
|
||||
FIXEDBYTES19,
|
||||
FIXEDBYTES20,
|
||||
FIXEDBYTES21,
|
||||
FIXEDBYTES22,
|
||||
FIXEDBYTES23,
|
||||
FIXEDBYTES24,
|
||||
FIXEDBYTES25,
|
||||
FIXEDBYTES26,
|
||||
FIXEDBYTES27,
|
||||
FIXEDBYTES28,
|
||||
FIXEDBYTES29,
|
||||
FIXEDBYTES30,
|
||||
FIXEDBYTES31,
|
||||
FIXEDBYTES32,
|
||||
BYTES,
|
||||
ADDRESS,
|
||||
FUNCTION,
|
||||
@ -812,6 +906,7 @@ struct ExpressionGenerator
|
||||
OR,
|
||||
LIT,
|
||||
MEMBERACCESS,
|
||||
MAGICEXPR,
|
||||
RLMAX
|
||||
};
|
||||
|
||||
@ -843,10 +938,9 @@ struct ExpressionGenerator
|
||||
std::optional<std::pair<SolidityTypePtr, std::string>> rLValueOrLiteral(
|
||||
std::pair<SolidityTypePtr, std::string>& _typeName
|
||||
);
|
||||
std::optional<std::pair<SolidityTypePtr, std::string>> memberAccessExpr(
|
||||
std::pair<SolidityTypePtr, std::string>& _typeName
|
||||
);
|
||||
std::pair<SolidityTypePtr, std::string> memberAccessExpr(SolidityTypePtr& _typeName);
|
||||
RLValueExpr expressionType(SolidityTypePtr& _typePtr);
|
||||
std::pair<SolidityTypePtr, std::string> magicExpr(SolidityTypePtr& _type);
|
||||
|
||||
void incrementNestingDepth()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user