mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #4849 from lastmjs/develop
Introduce static elementary types to use
This commit is contained in:
commit
5f4a2d2cad
@ -92,7 +92,7 @@ To run a subset of tests, filters can be used:
|
|||||||
``soltest -t TestSuite/TestName -- --ipcpath /tmp/testeth/geth.ipc --testpath ./test``,
|
``soltest -t TestSuite/TestName -- --ipcpath /tmp/testeth/geth.ipc --testpath ./test``,
|
||||||
where ``TestName`` can be a wildcard ``*``.
|
where ``TestName`` can be a wildcard ``*``.
|
||||||
|
|
||||||
Alternatively, there is a testing script at ``scripts/test.sh`` which executes all tests and runs
|
Alternatively, there is a testing script at ``scripts/tests.sh`` which executes all tests and runs
|
||||||
``cpp-ethereum`` automatically if it is in the path (but does not download it).
|
``cpp-ethereum`` automatically if it is in the path (but does not download it).
|
||||||
|
|
||||||
Travis CI even runs some additional tests (including ``solc-js`` and testing third party Solidity frameworks) that require compiling the Emscripten target.
|
Travis CI even runs some additional tests (including ``solc-js`` and testing third party Solidity frameworks) that require compiling the Emscripten target.
|
||||||
|
@ -535,7 +535,7 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c
|
|||||||
toString(arguments.size()) +
|
toString(arguments.size()) +
|
||||||
" were provided."
|
" were provided."
|
||||||
);
|
);
|
||||||
if (arguments.size() >= 1 && !type(*arguments.front())->isImplicitlyConvertibleTo(ArrayType(DataLocation::Memory)))
|
if (arguments.size() >= 1 && !type(*arguments.front())->isImplicitlyConvertibleTo(ArrayType::bytesMemory()))
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
arguments.front()->location(),
|
arguments.front()->location(),
|
||||||
"Invalid type for argument in function call. "
|
"Invalid type for argument in function call. "
|
||||||
@ -2131,7 +2131,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
|
|||||||
"after argument-dependent lookup in " + exprType->toString() +
|
"after argument-dependent lookup in " + exprType->toString() +
|
||||||
(memberName == "value" ? " - did you forget the \"payable\" modifier?" : ".");
|
(memberName == "value" ? " - did you forget the \"payable\" modifier?" : ".");
|
||||||
if (exprType->category() == Type::Category::Contract)
|
if (exprType->category() == Type::Category::Contract)
|
||||||
for (auto const& addressMember: AddressType(StateMutability::Payable).nativeMembers(nullptr))
|
for (auto const& addressMember: AddressType::addressPayable().nativeMembers(nullptr))
|
||||||
if (addressMember.name == memberName)
|
if (addressMember.name == memberName)
|
||||||
{
|
{
|
||||||
Identifier const* var = dynamic_cast<Identifier const*>(&_memberAccess.expression());
|
Identifier const* var = dynamic_cast<Identifier const*>(&_memberAccess.expression());
|
||||||
|
@ -319,6 +319,9 @@ protected:
|
|||||||
class AddressType: public Type
|
class AddressType: public Type
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static AddressType& address() { static std::shared_ptr<AddressType> addr(std::make_shared<AddressType>(StateMutability::NonPayable)); return *addr; }
|
||||||
|
static AddressType& addressPayable() { static std::shared_ptr<AddressType> addr(std::make_shared<AddressType>(StateMutability::Payable)); return *addr; }
|
||||||
|
|
||||||
virtual Category category() const override { return Category::Address; }
|
virtual Category category() const override { return Category::Address; }
|
||||||
|
|
||||||
explicit AddressType(StateMutability _stateMutability);
|
explicit AddressType(StateMutability _stateMutability);
|
||||||
@ -361,6 +364,7 @@ public:
|
|||||||
{
|
{
|
||||||
Unsigned, Signed
|
Unsigned, Signed
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual Category category() const override { return Category::Integer; }
|
virtual Category category() const override { return Category::Integer; }
|
||||||
|
|
||||||
explicit IntegerType(unsigned _bits, Modifier _modifier = Modifier::Unsigned);
|
explicit IntegerType(unsigned _bits, Modifier _modifier = Modifier::Unsigned);
|
||||||
@ -661,6 +665,9 @@ protected:
|
|||||||
class ArrayType: public ReferenceType
|
class ArrayType: public ReferenceType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static ArrayType& bytesMemory() { static std::shared_ptr<ArrayType> addr(std::make_shared<ArrayType>(DataLocation::Memory)); return *addr; }
|
||||||
|
static ArrayType& stringMemory() { static std::shared_ptr<ArrayType> addr(std::make_shared<ArrayType>(DataLocation::Memory, true)); return *addr; }
|
||||||
|
|
||||||
virtual Category category() const override { return Category::Array; }
|
virtual Category category() const override { return Category::Array; }
|
||||||
|
|
||||||
/// Constructor for a byte array ("bytes") and string.
|
/// Constructor for a byte array ("bytes") and string.
|
||||||
|
@ -710,9 +710,9 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
|||||||
arguments.front()->accept(*this);
|
arguments.front()->accept(*this);
|
||||||
// Optimization: If type is bytes or string, then do not encode,
|
// Optimization: If type is bytes or string, then do not encode,
|
||||||
// but directly compute keccak256 on memory.
|
// but directly compute keccak256 on memory.
|
||||||
if (*argType == ArrayType(DataLocation::Memory) || *argType == ArrayType(DataLocation::Memory, true))
|
if (*argType == ArrayType::bytesMemory() || *argType == ArrayType::stringMemory())
|
||||||
{
|
{
|
||||||
ArrayUtils(m_context).retrieveLength(ArrayType(DataLocation::Memory));
|
ArrayUtils(m_context).retrieveLength(ArrayType::bytesMemory());
|
||||||
m_context << Instruction::SWAP1 << u256(0x20) << Instruction::ADD;
|
m_context << Instruction::SWAP1 << u256(0x20) << Instruction::ADD;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1086,7 +1086,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
|||||||
utils().abiDecode(targetTypes, false);
|
utils().abiDecode(targetTypes, false);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
utils().convertType(*firstArgType, ArrayType(DataLocation::Memory));
|
utils().convertType(*firstArgType, ArrayType::bytesMemory());
|
||||||
m_context << Instruction::DUP1 << u256(32) << Instruction::ADD;
|
m_context << Instruction::DUP1 << u256(32) << Instruction::ADD;
|
||||||
m_context << Instruction::SWAP1 << Instruction::MLOAD;
|
m_context << Instruction::SWAP1 << Instruction::MLOAD;
|
||||||
// stack now: <mem_pos> <length>
|
// stack now: <mem_pos> <length>
|
||||||
@ -1259,7 +1259,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
|||||||
identifier = FunctionType(*function).externalIdentifier();
|
identifier = FunctionType(*function).externalIdentifier();
|
||||||
else
|
else
|
||||||
solAssert(false, "Contract member is neither variable nor function.");
|
solAssert(false, "Contract member is neither variable nor function.");
|
||||||
utils().convertType(type, AddressType(type.isPayable() ? StateMutability::Payable : StateMutability::NonPayable), true);
|
utils().convertType(type, type.isPayable() ? AddressType::addressPayable() : AddressType::address(), true);
|
||||||
m_context << identifier;
|
m_context << identifier;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1277,7 +1277,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
|||||||
{
|
{
|
||||||
utils().convertType(
|
utils().convertType(
|
||||||
*_memberAccess.expression().annotation().type,
|
*_memberAccess.expression().annotation().type,
|
||||||
AddressType(StateMutability::NonPayable),
|
AddressType::address(),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
m_context << Instruction::BALANCE;
|
m_context << Instruction::BALANCE;
|
||||||
@ -1294,7 +1294,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
|||||||
else if ((set<string>{"call", "callcode", "delegatecall", "staticcall"}).count(member))
|
else if ((set<string>{"call", "callcode", "delegatecall", "staticcall"}).count(member))
|
||||||
utils().convertType(
|
utils().convertType(
|
||||||
*_memberAccess.expression().annotation().type,
|
*_memberAccess.expression().annotation().type,
|
||||||
AddressType(StateMutability::NonPayable),
|
AddressType::address(),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user