aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/codegen/ContractCompiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/codegen/ContractCompiler.cpp')
-rw-r--r--libsolidity/codegen/ContractCompiler.cpp37
1 files changed, 20 insertions, 17 deletions
diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp
index 2e3f5d7f..a0f196bc 100644
--- a/libsolidity/codegen/ContractCompiler.cpp
+++ b/libsolidity/codegen/ContractCompiler.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
- cpp-ethereum is distributed in the hope that it will be useful,
+ solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -102,6 +102,13 @@ void ContractCompiler::initializeContext(
m_context.resetVisitedNodes(&_contract);
}
+void ContractCompiler::appendCallValueCheck()
+{
+ // Throw if function is not payable but call contained ether.
+ m_context << Instruction::CALLVALUE;
+ m_context.appendConditionalJumpTo(m_context.errorTag());
+}
+
void ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _contract)
{
// Determine the arguments that are used for the base constructors.
@@ -137,6 +144,8 @@ void ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _c
appendConstructor(*constructor);
else if (auto c = m_context.nextConstructor(_contract))
appendBaseConstructor(*c);
+ else
+ appendCallValueCheck();
}
size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _contract)
@@ -184,6 +193,9 @@ void ContractCompiler::appendBaseConstructor(FunctionDefinition const& _construc
void ContractCompiler::appendConstructor(FunctionDefinition const& _constructor)
{
CompilerContext::LocationSetter locationSetter(m_context, _constructor);
+ if (!_constructor.isPayable())
+ appendCallValueCheck();
+
// copy constructor arguments from code to memory and then to stack, they are supplied after the actual program
if (!_constructor.parameters().empty())
{
@@ -251,11 +263,8 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac
if (fallback)
{
if (!fallback->isPayable())
- {
- // Throw if function is not payable but call contained ether.
- m_context << Instruction::CALLVALUE;
- m_context.appendConditionalJumpTo(m_context.errorTag());
- }
+ appendCallValueCheck();
+
eth::AssemblyItem returnTag = m_context.pushNewTag();
fallback->accept(*this);
m_context << returnTag;
@@ -274,11 +283,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac
// We have to allow this for libraries, because value of the previous
// call is still visible in the delegatecall.
if (!functionType->isPayable() && !_contract.isLibrary())
- {
- // Throw if function is not payable but call contained ether.
- m_context << Instruction::CALLVALUE;
- m_context.appendConditionalJumpTo(m_context.errorTag());
- }
+ appendCallValueCheck();
eth::AssemblyItem returnTag = m_context.pushNewTag();
m_context << CompilerUtils::dataStartOffset;
@@ -578,7 +583,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
// lvalue context
auto variable = dynamic_cast<VariableDeclaration const*>(decl);
solAssert(
- !!variable || !m_context.isLocalVariable(variable),
+ !!variable && m_context.isLocalVariable(variable),
"Can only assign to stack variables in inline assembly."
);
unsigned size = variable->type()->sizeOnStack();
@@ -857,8 +862,6 @@ void ContractCompiler::appendModifierOrFunctionCode()
CompilerUtils::sizeOnStack(modifier.parameters()) +
CompilerUtils::sizeOnStack(modifier.localVariables());
codeBlock = &modifier.body();
-
- codeBlock = &modifier.body();
}
}