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 | |
parent | 3da16b3e8af41a1d743a94d2e19822e82440a63d (diff) | |
download | dexon-solidity-ae1d040285d97c2be0eb9d3e94a983975459f879.tar.gz dexon-solidity-ae1d040285d97c2be0eb9d3e94a983975459f879.tar.zst dexon-solidity-ae1d040285d97c2be0eb9d3e94a983975459f879.zip |
Allow error string for ``require``.
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/GlobalContext.cpp | 1 | ||||
-rw-r--r-- | libsolidity/codegen/ExpressionCompiler.cpp | 26 |
2 files changed, 27 insertions, 0 deletions
diff --git a/libsolidity/analysis/GlobalContext.cpp b/libsolidity/analysis/GlobalContext.cpp index 822674af..c58d99fb 100644 --- a/libsolidity/analysis/GlobalContext.cpp +++ b/libsolidity/analysis/GlobalContext.cpp @@ -51,6 +51,7 @@ m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{ make_shared<MagicVariableDeclaration>("mulmod", make_shared<FunctionType>(strings{"uint256", "uint256", "uint256"}, strings{"uint256"}, FunctionType::Kind::MulMod, false, StateMutability::Pure)), make_shared<MagicVariableDeclaration>("now", make_shared<IntegerType>(256)), make_shared<MagicVariableDeclaration>("require", make_shared<FunctionType>(strings{"bool"}, strings{}, FunctionType::Kind::Require, false, StateMutability::Pure)), + make_shared<MagicVariableDeclaration>("require", make_shared<FunctionType>(strings{"bool", "string memory"}, strings{}, FunctionType::Kind::Require, false, StateMutability::Pure)), make_shared<MagicVariableDeclaration>("revert", make_shared<FunctionType>(strings(), strings(), FunctionType::Kind::Revert, false, StateMutability::Pure)), make_shared<MagicVariableDeclaration>("revert", make_shared<FunctionType>(strings{"string memory"}, strings(), FunctionType::Kind::Revert, false, StateMutability::Pure)), make_shared<MagicVariableDeclaration>("ripemd160", make_shared<FunctionType>(strings(), strings{"bytes20"}, FunctionType::Kind::RIPEMD160, true, StateMutability::Pure)), 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: |