From dcc16c81e26f31141ae766096873b5fd7741cdf5 Mon Sep 17 00:00:00 2001
From: chriseth <c@ethdev.com>
Date: Thu, 16 Feb 2017 11:45:06 +0100
Subject: Some checks for the existence of mobile type.

---
 Changelog.md                               | 1 +
 libsolidity/ast/Types.cpp                  | 7 +++++--
 libsolidity/codegen/ExpressionCompiler.cpp | 3 +++
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/Changelog.md b/Changelog.md
index bd514cfe..5684adbd 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -10,6 +10,7 @@ Bugfixes:
  * Commandline interface: Always escape filenames (replace ``/``, ``:`` and ``.`` with ``_``).
  * Commandline interface: Do not try creating paths ``.`` and ``..``.
  * Type system: Disallow arrays with negative length.
+ * Type system: Fix a crash related to invalid binary operators.
 
 ### 0.4.9 (2017-01-31)
 
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 5b7b4a2c..75dee6db 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -252,9 +252,9 @@ TypePointer Type::commonType(TypePointer const& _a, TypePointer const& _b)
 {
 	if (!_a || !_b)
 		return TypePointer();
-	else if (_b->isImplicitlyConvertibleTo(*_a->mobileType()))
+	else if (_a->mobileType() && _b->isImplicitlyConvertibleTo(*_a->mobileType()))
 		return _a->mobileType();
-	else if (_a->isImplicitlyConvertibleTo(*_b->mobileType()))
+	else if (_b->mobileType() && _a->isImplicitlyConvertibleTo(*_b->mobileType()))
 		return _b->mobileType();
 	else
 		return TypePointer();
@@ -1895,7 +1895,10 @@ TypePointer TupleType::closestTemporaryType(TypePointer const& _targetType) cons
 		size_t si = fillRight ? i : components().size() - i - 1;
 		size_t ti = fillRight ? i : targetComponents.size() - i - 1;
 		if (components()[si] && targetComponents[ti])
+		{
 			tempComponents[ti] = components()[si]->closestTemporaryType(targetComponents[ti]);
+			solAssert(tempComponents[ti], "");
+		}
 	}
 	return make_shared<TupleType>(tempComponents);
 }
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index 2ed19a83..1c2883cd 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -220,6 +220,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
 		rightIntermediateType = _assignment.rightHandSide().annotation().type->closestTemporaryType(
 			_assignment.leftHandSide().annotation().type
 		);
+	solAssert(rightIntermediateType, "");
 	utils().convertType(*_assignment.rightHandSide().annotation().type, *rightIntermediateType, cleanupNeeded);
 
 	_assignment.leftHandSide().accept(*this);
@@ -395,6 +396,7 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
 
 		TypePointer leftTargetType = commonType;
 		TypePointer rightTargetType = Token::isShiftOp(c_op) ? rightExpression.annotation().type->mobileType() : commonType;
+		solAssert(rightTargetType, "");
 
 		// for commutative operators, push the literal as late as possible to allow improved optimization
 		auto isLiteral = [](Expression const& _e)
@@ -808,6 +810,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
 			arguments[0]->accept(*this);
 			// stack: newLength storageSlot slotOffset argValue
 			TypePointer type = arguments[0]->annotation().type->closestTemporaryType(arrayType->baseType());
+			solAssert(type, "");
 			utils().convertType(*arguments[0]->annotation().type, *type);
 			utils().moveToStackTop(1 + type->sizeOnStack());
 			utils().moveToStackTop(1 + type->sizeOnStack());
-- 
cgit v1.2.3