mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #4062 from ethereum/revert-variable
Fix revert with reason coming from a string variable
This commit is contained in:
commit
dce6224052
@ -15,10 +15,10 @@ Features:
|
|||||||
* Type Checker: Warn about wildcard tuple assignments (this will turn into an error with version 0.5.0).
|
* Type Checker: Warn about wildcard tuple assignments (this will turn into an error with version 0.5.0).
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
* Code Generator: Fix ``revert`` with reason coming from a state or local string variable.
|
||||||
* Type Checker: Show proper error when trying to ``emit`` a non-event.
|
* Type Checker: Show proper error when trying to ``emit`` a non-event.
|
||||||
* Type Checker: Warn about empty tuple components (this will turn into an error with version 0.5.0).
|
* Type Checker: Warn about empty tuple components (this will turn into an error with version 0.5.0).
|
||||||
|
|
||||||
|
|
||||||
### 0.4.23 (2018-04-19)
|
### 0.4.23 (2018-04-19)
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
@ -89,7 +89,6 @@ void CompilerUtils::revertWithStringData(Type const& _argumentType)
|
|||||||
abiEncode({_argumentType.shared_from_this()}, {make_shared<ArrayType>(DataLocation::Memory, true)});
|
abiEncode({_argumentType.shared_from_this()}, {make_shared<ArrayType>(DataLocation::Memory, true)});
|
||||||
toSizeAfterFreeMemoryPointer();
|
toSizeAfterFreeMemoryPointer();
|
||||||
m_context << Instruction::REVERT;
|
m_context << Instruction::REVERT;
|
||||||
m_context.adjustStackOffset(_argumentType.sizeOnStack());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned CompilerUtils::loadFromMemory(
|
unsigned CompilerUtils::loadFromMemory(
|
||||||
|
@ -933,7 +933,11 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
|||||||
// condition was not met, flag an error
|
// condition was not met, flag an error
|
||||||
m_context.appendInvalid();
|
m_context.appendInvalid();
|
||||||
else if (arguments.size() > 1)
|
else if (arguments.size() > 1)
|
||||||
|
{
|
||||||
utils().revertWithStringData(*arguments.at(1)->annotation().type);
|
utils().revertWithStringData(*arguments.at(1)->annotation().type);
|
||||||
|
// Here, the argument is consumed, but in the other branch, it is still there.
|
||||||
|
m_context.adjustStackOffset(arguments.at(1)->annotation().type->sizeOnStack());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_context.appendRevert();
|
m_context.appendRevert();
|
||||||
// the success branch
|
// the success branch
|
||||||
|
@ -10660,12 +10660,24 @@ BOOST_AUTO_TEST_CASE(revert_with_cause)
|
|||||||
{
|
{
|
||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
contract D {
|
contract D {
|
||||||
|
string constant msg1 = "test1234567890123456789012345678901234567890";
|
||||||
|
string msg2 = "test1234567890123456789012345678901234567890";
|
||||||
function f() public {
|
function f() public {
|
||||||
revert("test123");
|
revert("test123");
|
||||||
}
|
}
|
||||||
function g() public {
|
function g() public {
|
||||||
revert("test1234567890123456789012345678901234567890");
|
revert("test1234567890123456789012345678901234567890");
|
||||||
}
|
}
|
||||||
|
function h() public {
|
||||||
|
revert(msg1);
|
||||||
|
}
|
||||||
|
function i() public {
|
||||||
|
revert(msg2);
|
||||||
|
}
|
||||||
|
function j() public {
|
||||||
|
string memory msg3 = "test1234567890123456789012345678901234567890";
|
||||||
|
revert(msg3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
contract C {
|
contract C {
|
||||||
D d = new D();
|
D d = new D();
|
||||||
@ -10686,6 +10698,15 @@ BOOST_AUTO_TEST_CASE(revert_with_cause)
|
|||||||
function g() public returns (bool, bytes) {
|
function g() public returns (bool, bytes) {
|
||||||
return forward(address(d), msg.data);
|
return forward(address(d), msg.data);
|
||||||
}
|
}
|
||||||
|
function h() public returns (bool, bytes) {
|
||||||
|
return forward(address(d), msg.data);
|
||||||
|
}
|
||||||
|
function i() public returns (bool, bytes) {
|
||||||
|
return forward(address(d), msg.data);
|
||||||
|
}
|
||||||
|
function j() public returns (bool, bytes) {
|
||||||
|
return forward(address(d), msg.data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
compileAndRun(sourceCode, 0, "C");
|
compileAndRun(sourceCode, 0, "C");
|
||||||
@ -10693,6 +10714,9 @@ BOOST_AUTO_TEST_CASE(revert_with_cause)
|
|||||||
bytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};
|
bytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};
|
||||||
ABI_CHECK(callContractFunction("f()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 7, "test123") + bytes(28, 0) : bytes());
|
ABI_CHECK(callContractFunction("f()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 7, "test123") + bytes(28, 0) : bytes());
|
||||||
ABI_CHECK(callContractFunction("g()"), haveReturndata ? encodeArgs(0, 0x40, 0x84) + errorSignature + encodeArgs(0x20, 44, "test1234567890123456789012345678901234567890") + bytes(28, 0): bytes());
|
ABI_CHECK(callContractFunction("g()"), haveReturndata ? encodeArgs(0, 0x40, 0x84) + errorSignature + encodeArgs(0x20, 44, "test1234567890123456789012345678901234567890") + bytes(28, 0): bytes());
|
||||||
|
ABI_CHECK(callContractFunction("h()"), haveReturndata ? encodeArgs(0, 0x40, 0x84) + errorSignature + encodeArgs(0x20, 44, "test1234567890123456789012345678901234567890") + bytes(28, 0): bytes());
|
||||||
|
ABI_CHECK(callContractFunction("i()"), haveReturndata ? encodeArgs(0, 0x40, 0x84) + errorSignature + encodeArgs(0x20, 44, "test1234567890123456789012345678901234567890") + bytes(28, 0): bytes());
|
||||||
|
ABI_CHECK(callContractFunction("j()"), haveReturndata ? encodeArgs(0, 0x40, 0x84) + errorSignature + encodeArgs(0x20, 44, "test1234567890123456789012345678901234567890") + bytes(28, 0): bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(require_with_message)
|
BOOST_AUTO_TEST_CASE(require_with_message)
|
||||||
@ -10701,6 +10725,7 @@ BOOST_AUTO_TEST_CASE(require_with_message)
|
|||||||
contract D {
|
contract D {
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
string storageError = "abc";
|
string storageError = "abc";
|
||||||
|
string constant constantError = "abc";
|
||||||
function f(uint x) public {
|
function f(uint x) public {
|
||||||
require(x > 7, "failed");
|
require(x > 7, "failed");
|
||||||
}
|
}
|
||||||
@ -10718,6 +10743,13 @@ BOOST_AUTO_TEST_CASE(require_with_message)
|
|||||||
function h() public {
|
function h() public {
|
||||||
require(false, storageError);
|
require(false, storageError);
|
||||||
}
|
}
|
||||||
|
function i() public {
|
||||||
|
require(false, constantError);
|
||||||
|
}
|
||||||
|
function j() public {
|
||||||
|
string memory errMsg = "msg";
|
||||||
|
require(false, errMsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
contract C {
|
contract C {
|
||||||
D d = new D();
|
D d = new D();
|
||||||
@ -10741,6 +10773,12 @@ BOOST_AUTO_TEST_CASE(require_with_message)
|
|||||||
function h() public returns (bool, bytes) {
|
function h() public returns (bool, bytes) {
|
||||||
return forward(address(d), msg.data);
|
return forward(address(d), msg.data);
|
||||||
}
|
}
|
||||||
|
function i() public returns (bool, bytes) {
|
||||||
|
return forward(address(d), msg.data);
|
||||||
|
}
|
||||||
|
function j() public returns (bool, bytes) {
|
||||||
|
return forward(address(d), msg.data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
compileAndRun(sourceCode, 0, "C");
|
compileAndRun(sourceCode, 0, "C");
|
||||||
@ -10751,6 +10789,8 @@ BOOST_AUTO_TEST_CASE(require_with_message)
|
|||||||
ABI_CHECK(callContractFunction("g()"), haveReturndata ? encodeArgs(1, 0x40, 0) : bytes());
|
ABI_CHECK(callContractFunction("g()"), haveReturndata ? encodeArgs(1, 0x40, 0) : bytes());
|
||||||
ABI_CHECK(callContractFunction("g()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 18, "only on second run") + bytes(28, 0) : bytes());
|
ABI_CHECK(callContractFunction("g()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 18, "only on second run") + bytes(28, 0) : bytes());
|
||||||
ABI_CHECK(callContractFunction("h()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 3, "abc") + bytes(28, 0): bytes());
|
ABI_CHECK(callContractFunction("h()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 3, "abc") + bytes(28, 0): bytes());
|
||||||
|
ABI_CHECK(callContractFunction("i()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 3, "abc") + bytes(28, 0): bytes());
|
||||||
|
ABI_CHECK(callContractFunction("j()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 3, "msg") + bytes(28, 0): bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(bubble_up_error_messages)
|
BOOST_AUTO_TEST_CASE(bubble_up_error_messages)
|
||||||
|
Loading…
Reference in New Issue
Block a user