mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #10424 from ethereum/ir-modifiers
Add unimplemented assert for modifiers in the IR
This commit is contained in:
commit
fb01884e69
@ -249,6 +249,7 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function)
|
|||||||
{
|
{
|
||||||
string functionName = IRNames::function(_function);
|
string functionName = IRNames::function(_function);
|
||||||
return m_context.functionCollector().createFunction(functionName, [&]() {
|
return m_context.functionCollector().createFunction(functionName, [&]() {
|
||||||
|
solUnimplementedAssert(_function.modifiers().empty(), "Modifiers not implemented yet.");
|
||||||
Whiskers t(R"(
|
Whiskers t(R"(
|
||||||
function <functionName>(<params>)<?+retParams> -> <retParams></+retParams> {
|
function <functionName>(<params>)<?+retParams> -> <retParams></+retParams> {
|
||||||
<initReturnVariables>
|
<initReturnVariables>
|
||||||
@ -521,8 +522,16 @@ void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contra
|
|||||||
)");
|
)");
|
||||||
vector<string> params;
|
vector<string> params;
|
||||||
if (contract->constructor())
|
if (contract->constructor())
|
||||||
|
{
|
||||||
|
for (auto const& modifierInvocation: contract->constructor()->modifiers())
|
||||||
|
// This can be ContractDefinition too for super arguments. That is supported.
|
||||||
|
solUnimplementedAssert(
|
||||||
|
!dynamic_cast<ModifierDefinition const*>(modifierInvocation->name()->annotation().referencedDeclaration),
|
||||||
|
"Modifiers not implemented yet."
|
||||||
|
);
|
||||||
for (ASTPointer<VariableDeclaration> const& varDecl: contract->constructor()->parameters())
|
for (ASTPointer<VariableDeclaration> const& varDecl: contract->constructor()->parameters())
|
||||||
params += m_context.addLocalVariable(*varDecl).stackSlots();
|
params += m_context.addLocalVariable(*varDecl).stackSlots();
|
||||||
|
}
|
||||||
t("params", joinHumanReadable(params));
|
t("params", joinHumanReadable(params));
|
||||||
vector<string> baseParams = listAllParams(baseConstructorParams);
|
vector<string> baseParams = listAllParams(baseConstructorParams);
|
||||||
t("baseParams", joinHumanReadable(baseParams));
|
t("baseParams", joinHumanReadable(baseParams));
|
||||||
|
@ -4481,30 +4481,6 @@ BOOST_AUTO_TEST_CASE(non_payable_throw)
|
|||||||
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
|
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(no_nonpayable_circumvention_by_modifier)
|
|
||||||
{
|
|
||||||
char const* sourceCode = R"(
|
|
||||||
contract C {
|
|
||||||
modifier tryCircumvent {
|
|
||||||
if (false) _; // avoid the function, we should still not accept ether
|
|
||||||
}
|
|
||||||
function f() tryCircumvent public returns (uint) {
|
|
||||||
return msgvalue();
|
|
||||||
}
|
|
||||||
function msgvalue() internal returns (uint) {
|
|
||||||
return msg.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
ALSO_VIA_YUL(
|
|
||||||
DISABLE_EWASM_TESTRUN()
|
|
||||||
|
|
||||||
compileAndRun(sourceCode);
|
|
||||||
ABI_CHECK(callContractFunctionWithValue("f()", 27), encodeArgs());
|
|
||||||
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(mem_resize_is_not_paid_at_call)
|
BOOST_AUTO_TEST_CASE(mem_resize_is_not_paid_at_call)
|
||||||
{
|
{
|
||||||
// This tests that memory resize for return values is not paid during the call, which would
|
// This tests that memory resize for return values is not paid during the call, which would
|
||||||
|
@ -11,10 +11,23 @@ contract C {
|
|||||||
function f() public m returns (bool) {
|
function f() public m returns (bool) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
modifier n {
|
||||||
|
uint256 a = 1;
|
||||||
|
assembly {
|
||||||
|
a := 2
|
||||||
|
}
|
||||||
|
if (a != 2)
|
||||||
|
_;
|
||||||
|
revert();
|
||||||
|
}
|
||||||
|
|
||||||
|
function g() public n returns (bool) {
|
||||||
|
// This statement should never execute.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====
|
|
||||||
// compileViaYul: also
|
|
||||||
// compileToEwasm: also
|
|
||||||
// ----
|
// ----
|
||||||
// f() -> true
|
// f() -> true
|
||||||
|
// g() -> FAILURE
|
||||||
|
@ -3,7 +3,8 @@ contract C {
|
|||||||
modifier run() {
|
modifier run() {
|
||||||
for (uint256 i = 0; i < 10; i++) {
|
for (uint256 i = 0; i < 10; i++) {
|
||||||
_;
|
_;
|
||||||
break;
|
if (i == 1)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13,10 +14,7 @@ contract C {
|
|||||||
x = t;
|
x = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ====
|
|
||||||
// compileViaYul: also
|
|
||||||
// compileToEwasm: also
|
|
||||||
// ----
|
// ----
|
||||||
// x() -> 0
|
// x() -> 0
|
||||||
// f() ->
|
// f() ->
|
||||||
// x() -> 1
|
// x() -> 2
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
contract C {
|
contract C {
|
||||||
uint256 public x;
|
uint256 public x;
|
||||||
modifier run() {
|
modifier m() {
|
||||||
for (uint256 i = 0; i < 10; i++) {
|
for (uint256 i = 0; i < 10; i++) {
|
||||||
_;
|
_;
|
||||||
break;
|
++x;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function f() public run {
|
function f() public m m m returns (uint) {
|
||||||
uint256 k = x;
|
for (uint256 i = 0; i < 10; i++) {
|
||||||
uint256 t = k + 1;
|
++x;
|
||||||
x = t;
|
return 42;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ====
|
|
||||||
// compileViaYul: also
|
|
||||||
// compileToEwasm: also
|
|
||||||
// ----
|
// ----
|
||||||
// x() -> 0
|
// x() -> 0
|
||||||
// f() ->
|
// f() -> 42
|
||||||
// x() -> 1
|
// x() -> 4
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
contract C {
|
||||||
|
modifier tryCircumvent {
|
||||||
|
if (false) _; // avoid the function, we should still not accept ether
|
||||||
|
}
|
||||||
|
function f() tryCircumvent public returns (uint) {
|
||||||
|
return msgvalue();
|
||||||
|
}
|
||||||
|
function msgvalue() internal returns (uint) {
|
||||||
|
return msg.value;
|
||||||
|
}
|
||||||
|
// TODO: remove this helper function once isoltest supports balance checking
|
||||||
|
function balance() external returns (uint) {
|
||||||
|
return address(this).balance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// f(), 27 wei -> FAILURE
|
||||||
|
// balance() -> 0
|
Loading…
Reference in New Issue
Block a user