aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/analysis/TypeChecker.cpp58
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp6
2 files changed, 53 insertions, 11 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 82421749..a222bdf0 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -1067,6 +1067,7 @@ void TypeChecker::endVisit(EmitStatement const& _emit)
{
if (
_emit.eventCall().annotation().kind != FunctionCallKind::FunctionCall ||
+ type(_emit.eventCall().expression())->category() != Type::Category::Function ||
dynamic_cast<FunctionType const&>(*type(_emit.eventCall().expression())).kind() != FunctionType::Kind::Event
)
m_errorReporter.typeError(_emit.eventCall().expression().location(), "Expression has to be an event invocation.");
@@ -1075,6 +1076,7 @@ void TypeChecker::endVisit(EmitStatement const& _emit)
bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
{
+ bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
if (!_statement.initialValue())
{
// No initial value is only permitted for single variables with specified type.
@@ -1091,7 +1093,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
if (varDecl.referenceLocation() == VariableDeclaration::Location::Default)
errorText += " Did you mean '<type> memory " + varDecl.name() + "'?";
solAssert(m_scope, "");
- if (m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050))
+ if (v050)
m_errorReporter.declarationError(varDecl.location(), errorText);
else
m_errorReporter.warning(varDecl.location(), errorText);
@@ -1131,12 +1133,33 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
") in value for variable assignment (0) needed"
);
}
- else if (valueTypes.size() != variables.size() && !variables.front() && !variables.back())
- m_errorReporter.fatalTypeError(
- _statement.location(),
- "Wildcard both at beginning and end of variable declaration list is only allowed "
- "if the number of components is equal."
- );
+ else if (valueTypes.size() != variables.size())
+ {
+ if (v050)
+ m_errorReporter.fatalTypeError(
+ _statement.location(),
+ "Different number of components on the left hand side (" +
+ toString(variables.size()) +
+ ") than on the right hand side (" +
+ toString(valueTypes.size()) +
+ ")."
+ );
+ else if (!variables.front() && !variables.back())
+ m_errorReporter.fatalTypeError(
+ _statement.location(),
+ "Wildcard both at beginning and end of variable declaration list is only allowed "
+ "if the number of components is equal."
+ );
+ else
+ m_errorReporter.warning(
+ _statement.location(),
+ "Different number of components on the left hand side (" +
+ toString(variables.size()) +
+ ") than on the right hand side (" +
+ toString(valueTypes.size()) +
+ ")."
+ );
+ }
size_t minNumValues = variables.size();
if (!variables.empty() && (!variables.back() || !variables.front()))
--minNumValues;
@@ -1334,6 +1357,7 @@ bool TypeChecker::visit(Conditional const& _conditional)
bool TypeChecker::visit(Assignment const& _assignment)
{
+ bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
requireLValue(_assignment.leftHandSide());
TypePointer t = type(_assignment.leftHandSide());
_assignment.annotation().type = t;
@@ -1346,11 +1370,29 @@ bool TypeChecker::visit(Assignment const& _assignment)
);
// Sequenced assignments of tuples is not valid, make the result a "void" type.
_assignment.annotation().type = make_shared<TupleType>();
+
expectType(_assignment.rightHandSide(), *tupleType);
// expectType does not cause fatal errors, so we have to check again here.
- if (dynamic_cast<TupleType const*>(type(_assignment.rightHandSide()).get()))
+ if (TupleType const* rhsType = dynamic_cast<TupleType const*>(type(_assignment.rightHandSide()).get()))
+ {
checkDoubleStorageAssignment(_assignment);
+ // @todo For 0.5.0, this code shoud move to TupleType::isImplicitlyConvertibleTo,
+ // but we cannot do it right now.
+ if (rhsType->components().size() != tupleType->components().size())
+ {
+ string message =
+ "Different number of components on the left hand side (" +
+ toString(tupleType->components().size()) +
+ ") than on the right hand side (" +
+ toString(rhsType->components().size()) +
+ ").";
+ if (v050)
+ m_errorReporter.typeError(_assignment.location(), message);
+ else
+ m_errorReporter.warning(_assignment.location(), message);
+ }
+ }
}
else if (t->category() == Type::Category::Mapping)
{
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index fc1ff0eb..a39e799c 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -110,7 +110,7 @@ void CompilerUtils::loadFromMemoryDynamic(
bool _padToWordBoundaries,
bool _keepUpdatedMemoryOffset
)
-{
+{
if (_keepUpdatedMemoryOffset)
m_context << Instruction::DUP1;
@@ -396,7 +396,7 @@ void CompilerUtils::encodeToMemory(
// leave end_of_mem as dyn head pointer
m_context << Instruction::DUP1 << u256(32) << Instruction::ADD;
dynPointers++;
- solAssert((argSize + dynPointers) < 16, "Stack too deep, try using less variables.");
+ solAssert((argSize + dynPointers) < 16, "Stack too deep, try using fewer variables.");
}
else
{
@@ -741,7 +741,7 @@ void CompilerUtils::convertType(
else if (targetTypeCategory == Type::Category::FixedPoint)
{
solAssert(
- stackTypeCategory == Type::Category::Integer ||
+ stackTypeCategory == Type::Category::Integer ||
stackTypeCategory == Type::Category::RationalNumber ||
stackTypeCategory == Type::Category::FixedPoint,
"Invalid conversion to FixedMxNType requested."