aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/analysis/TypeChecker.cpp18
-rw-r--r--libsolidity/ast/Types.cpp16
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp3
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp18
4 files changed, 44 insertions, 11 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index f871e3a1..46f4f7f6 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -880,6 +880,10 @@ bool TypeChecker::visit(Conditional const& _conditional)
TypePointer trueType = type(_conditional.trueExpression())->mobileType();
TypePointer falseType = type(_conditional.falseExpression())->mobileType();
+ if (!trueType)
+ fatalTypeError(_conditional.trueExpression().location(), "Invalid mobile type.");
+ if (!falseType)
+ fatalTypeError(_conditional.falseExpression().location(), "Invalid mobile type.");
TypePointer commonType = Type::commonType(trueType, falseType);
if (!commonType)
@@ -986,10 +990,16 @@ bool TypeChecker::visit(TupleExpression const& _tuple)
types.push_back(type(*components[i]));
if (_tuple.isInlineArray())
solAssert(!!types[i], "Inline array cannot have empty components");
- if (i == 0 && _tuple.isInlineArray())
- inlineArrayType = types[i]->mobileType();
- else if (_tuple.isInlineArray() && inlineArrayType)
- inlineArrayType = Type::commonType(inlineArrayType, types[i]->mobileType());
+ if (_tuple.isInlineArray())
+ {
+ if ((i == 0 || inlineArrayType) && !types[i]->mobileType())
+ fatalTypeError(components[i]->location(), "Invalid mobile type.");
+
+ if (i == 0)
+ inlineArrayType = types[i]->mobileType();
+ else if (inlineArrayType)
+ inlineArrayType = Type::commonType(inlineArrayType, types[i]->mobileType());
+ }
}
else
types.push_back(TypePointer());
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 88bdee9f..7cfed3c8 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -198,7 +198,9 @@ TypePointer Type::forLiteral(Literal const& _literal)
TypePointer Type::commonType(TypePointer const& _a, TypePointer const& _b)
{
- if (_b->isImplicitlyConvertibleTo(*_a))
+ if (!_a || !_b)
+ return TypePointer();
+ else if (_b->isImplicitlyConvertibleTo(*_a))
return _a;
else if (_a->isImplicitlyConvertibleTo(*_b))
return _b;
@@ -1661,7 +1663,17 @@ TypePointer TupleType::mobileType() const
{
TypePointers mobiles;
for (auto const& c: components())
- mobiles.push_back(c ? c->mobileType() : TypePointer());
+ {
+ if (c)
+ {
+ auto mt = c->mobileType();
+ if (!mt)
+ return TypePointer();
+ mobiles.push_back(mt);
+ }
+ else
+ mobiles.push_back(TypePointer());
+ }
return make_shared<TupleType>(mobiles);
}
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index ec496df8..e064c1a6 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -368,8 +368,11 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
m_context << (u256(1) << (256 - targetBytesType.numBytes() * 8)) << Instruction::MUL;
}
else if (targetTypeCategory == Type::Category::Enum)
+ {
+ solAssert(_typeOnStack.mobileType(), "");
// just clean
convertType(_typeOnStack, *_typeOnStack.mobileType(), true);
+ }
else if (targetTypeCategory == Type::Category::FixedPoint)
{
solAssert(
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index 98b7f6e5..9a096e2d 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -56,8 +56,10 @@ void ExpressionCompiler::appendStateVariableInitialization(VariableDeclaration c
if (_varDecl.annotation().type->dataStoredIn(DataLocation::Storage))
{
// reference type, only convert value to mobile type and do final conversion in storeValue.
- utils().convertType(*type, *type->mobileType());
- type = type->mobileType();
+ auto mt = type->mobileType();
+ solAssert(mt, "");
+ utils().convertType(*type, *mt);
+ type = mt;
}
else
{
@@ -1431,11 +1433,17 @@ void ExpressionCompiler::appendExternalFunctionCall(
// Evaluate arguments.
TypePointers argumentTypes;
TypePointers parameterTypes = _functionType.parameterTypes();
- bool manualFunctionId =
+ bool manualFunctionId = false;
+ if (
(funKind == FunctionKind::Bare || funKind == FunctionKind::BareCallCode || funKind == FunctionKind::BareDelegateCall) &&
- !_arguments.empty() &&
- _arguments.front()->annotation().type->mobileType()->calldataEncodedSize(false) ==
+ !_arguments.empty()
+ )
+ {
+ solAssert(_arguments.front()->annotation().type->mobileType(), "");
+ manualFunctionId =
+ _arguments.front()->annotation().type->mobileType()->calldataEncodedSize(false) ==
CompilerUtils::dataStartOffset;
+ }
if (manualFunctionId)
{
// If we have a Bare* and the first type has exactly 4 bytes, use it as