mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[isoltest] Adds support for fallback and ether functions.
This commit is contained in:
parent
02af613fa5
commit
e92b921123
@ -92,6 +92,12 @@ public:
|
||||
return callFallbackWithValue(0);
|
||||
}
|
||||
|
||||
bytes const& callLowLevel(bytes const& _data, u256 const& _value)
|
||||
{
|
||||
sendMessage(_data, false, _value);
|
||||
return m_output;
|
||||
}
|
||||
|
||||
bytes const& callContractFunctionWithValueNoEncoding(std::string _sig, u256 const& _value, bytes const& _arguments)
|
||||
{
|
||||
FixedHash<4> hash(dev::keccak256(_sig));
|
||||
|
@ -98,7 +98,9 @@ TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePref
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes output = callContractFunctionWithValueNoEncoding(
|
||||
bytes output = test.call().useCallWithoutSignature ?
|
||||
callLowLevel(test.call().arguments.rawBytes(), test.call().value) :
|
||||
callContractFunctionWithValueNoEncoding(
|
||||
test.call().signature,
|
||||
test.call().value,
|
||||
test.call().arguments.rawBytes()
|
||||
|
@ -2514,23 +2514,6 @@ BOOST_AUTO_TEST_CASE(super_alone)
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(fallback_function)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract A {
|
||||
uint data;
|
||||
function() external { data = 1; }
|
||||
function getData() public returns (uint r) { return data; }
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("getData()"), encodeArgs(0));
|
||||
ABI_CHECK(callContractFunction(""), encodeArgs());
|
||||
ABI_CHECK(callContractFunction("getData()"), encodeArgs(1));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(inherited_fallback_function)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
|
23
test/libsolidity/semanticTests/smoke/fallback.sol
Normal file
23
test/libsolidity/semanticTests/smoke/fallback.sol
Normal file
@ -0,0 +1,23 @@
|
||||
contract A {
|
||||
uint public data;
|
||||
uint public balance;
|
||||
bytes public externalData;
|
||||
function() external payable {
|
||||
data += 1;
|
||||
balance = msg.value;
|
||||
externalData = msg.data;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// data() -> 0
|
||||
// ()
|
||||
// data() -> 1
|
||||
// (): hex"42ef"
|
||||
// data() -> 2
|
||||
// externalData() -> 0x20, 2, left(0x42ef)
|
||||
// balance() -> 0
|
||||
// (), 1 ether
|
||||
// balance() -> 1
|
||||
// (), 2 ether: hex"fefe"
|
||||
// balance() -> 2
|
||||
// externalData() -> 0x20, 2, left(0xfefe)
|
@ -262,6 +262,9 @@ struct FunctionCall
|
||||
DisplayMode displayMode = DisplayMode::SingleLine;
|
||||
/// Marks this function call as the constructor.
|
||||
bool isConstructor = false;
|
||||
/// If this function call's signature has no name and no arguments,
|
||||
/// a low-level call with unstructured calldata will be issued.
|
||||
bool useCallWithoutSignature = false;
|
||||
/// Marks this function call as "short-handed", meaning
|
||||
/// no `->` declared.
|
||||
bool omitsArrow = true;
|
||||
|
@ -75,7 +75,7 @@ vector<dev::solidity::test::FunctionCall> TestFileParser::parseFunctionCalls(siz
|
||||
|
||||
try
|
||||
{
|
||||
call.signature = parseFunctionSignature();
|
||||
tie(call.signature, call.useCallWithoutSignature) = parseFunctionSignature();
|
||||
if (accept(Token::Comma, true))
|
||||
call.value = parseFunctionCallValue();
|
||||
if (accept(Token::Colon, true))
|
||||
@ -148,10 +148,17 @@ bool TestFileParser::expect(soltest::Token _token, bool const _advance)
|
||||
return true;
|
||||
}
|
||||
|
||||
string TestFileParser::parseFunctionSignature()
|
||||
pair<string, bool> TestFileParser::parseFunctionSignature()
|
||||
{
|
||||
string signature = m_scanner.currentLiteral();
|
||||
string signature;
|
||||
bool hasName = false;
|
||||
|
||||
if (accept(Token::Identifier, false))
|
||||
{
|
||||
hasName = true;
|
||||
signature = m_scanner.currentLiteral();
|
||||
expect(Token::Identifier);
|
||||
}
|
||||
|
||||
signature += formatToken(Token::LParen);
|
||||
expect(Token::LParen);
|
||||
@ -169,11 +176,15 @@ string TestFileParser::parseFunctionSignature()
|
||||
if (accept(Token::Arrow, true))
|
||||
throw Error(Error::Type::ParserError, "Invalid signature detected: " + signature);
|
||||
|
||||
if (!hasName && !parameters.empty())
|
||||
throw Error(Error::Type::ParserError, "Signatures without a name cannot have parameters: " + signature);
|
||||
else
|
||||
signature += parameters;
|
||||
|
||||
expect(Token::RParen);
|
||||
signature += formatToken(Token::RParen);
|
||||
return signature;
|
||||
|
||||
return {signature, !hasName};
|
||||
}
|
||||
|
||||
u256 TestFileParser::parseFunctionCallValue()
|
||||
|
@ -46,6 +46,8 @@ namespace test
|
||||
* // -> 2, 3
|
||||
* // h(uint256), 1 ether: 42
|
||||
* // -> FAILURE # If REVERT or other EVM failure was detected #
|
||||
* // () # Call fallback function #
|
||||
* // (), 1 ether # Call ether function #
|
||||
* ...
|
||||
*/
|
||||
class TestFileParser
|
||||
@ -128,8 +130,10 @@ private:
|
||||
bool accept(soltest::Token _token, bool const _expect = false);
|
||||
bool expect(soltest::Token _token, bool const _advance = true);
|
||||
|
||||
/// Parses a function call signature in the form of f(uint256, ...).
|
||||
std::string parseFunctionSignature();
|
||||
/// Parses a function call signature in the form of `f(uint256, ...)` and
|
||||
/// returns the signature and a flag that indicates if the function name was
|
||||
/// empty. If so, the signature is not allowed to define any parameters.
|
||||
std::pair<std::string, bool> parseFunctionSignature();
|
||||
|
||||
/// Parses the optional ether value that can be passed alongside the
|
||||
/// function call arguments. Throws an InvalidEtherValueEncoding exception
|
||||
|
Loading…
Reference in New Issue
Block a user