diff options
author | chriseth <chris@ethereum.org> | 2017-12-30 21:35:45 +0800 |
---|---|---|
committer | chriseth <chris@ethereum.org> | 2018-04-12 19:09:37 +0800 |
commit | ae1d040285d97c2be0eb9d3e94a983975459f879 (patch) | |
tree | 6431baa6efc9e58f76fa8ae2dc1a9468388628ec /libsolidity/codegen | |
parent | 3da16b3e8af41a1d743a94d2e19822e82440a63d (diff) | |
download | dexon-solidity-ae1d040285d97c2be0eb9d3e94a983975459f879.tar dexon-solidity-ae1d040285d97c2be0eb9d3e94a983975459f879.tar.gz dexon-solidity-ae1d040285d97c2be0eb9d3e94a983975459f879.tar.bz2 dexon-solidity-ae1d040285d97c2be0eb9d3e94a983975459f879.tar.lz dexon-solidity-ae1d040285d97c2be0eb9d3e94a983975459f879.tar.xz dexon-solidity-ae1d040285d97c2be0eb9d3e94a983975459f879.tar.zst dexon-solidity-ae1d040285d97c2be0eb9d3e94a983975459f879.zip |
Allow error string for ``require``.
Diffstat (limited to 'libsolidity/codegen')
-rw-r--r-- | libsolidity/codegen/ExpressionCompiler.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index dc9fae21..cb92b030 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -917,16 +917,42 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) { arguments.front()->accept(*this); utils().convertType(*arguments.front()->annotation().type, *function.parameterTypes().front(), false); + if (arguments.size() > 1) + { + // Users probably expect the second argument to be evaluated + // even if the condition is false, as would be the case for an actual + // function call. + solAssert(arguments.size() == 2, ""); + solAssert(function.kind() == FunctionType::Kind::Require, ""); + arguments.at(1)->accept(*this); + utils().moveIntoStack(1, arguments.at(1)->annotation().type->sizeOnStack()); + } + // Stack: <error string (unconverted)> <condition> // jump if condition was met m_context << Instruction::ISZERO << Instruction::ISZERO; auto success = m_context.appendConditionalJump(); if (function.kind() == FunctionType::Kind::Assert) // condition was not met, flag an error m_context.appendInvalid(); + else if (arguments.size() > 1) + { + m_context << u256(0); + utils().moveIntoStack(arguments.at(1)->annotation().type->sizeOnStack(), 1); + utils().fetchFreeMemoryPointer(); + utils().abiEncode( + {make_shared<IntegerType>(256), arguments.at(1)->annotation().type}, + {make_shared<IntegerType>(256), make_shared<ArrayType>(DataLocation::Memory, true)} + ); + utils().toSizeAfterFreeMemoryPointer(); + m_context << Instruction::REVERT; + m_context.adjustStackOffset(arguments.at(1)->annotation().type->sizeOnStack()); + } else m_context.appendRevert(); // the success branch m_context << success; + if (arguments.size() > 1) + utils().popStackElement(*arguments.at(1)->annotation().type); break; } case FunctionType::Kind::GasLeft: |