aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-02-21 07:40:38 +0800
committerAlex Beregszaszi <alex@rtfs.hu>2018-03-21 22:53:29 +0800
commitcc2f71e4acede70f6c220d3d0ba407ab73c2024c (patch)
treeb280c6bbd441b395a3ed172bdb01d60f40ff15a7 /libsolidity
parent32c94f505901201126000eb12087251f5695acbd (diff)
downloaddexon-solidity-cc2f71e4acede70f6c220d3d0ba407ab73c2024c.tar
dexon-solidity-cc2f71e4acede70f6c220d3d0ba407ab73c2024c.tar.gz
dexon-solidity-cc2f71e4acede70f6c220d3d0ba407ab73c2024c.tar.bz2
dexon-solidity-cc2f71e4acede70f6c220d3d0ba407ab73c2024c.tar.lz
dexon-solidity-cc2f71e4acede70f6c220d3d0ba407ab73c2024c.tar.xz
dexon-solidity-cc2f71e4acede70f6c220d3d0ba407ab73c2024c.tar.zst
dexon-solidity-cc2f71e4acede70f6c220d3d0ba407ab73c2024c.zip
Move dynamic type removal out of the type system.
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/analysis/TypeChecker.cpp12
-rw-r--r--libsolidity/ast/Types.cpp23
-rw-r--r--libsolidity/ast/Types.h3
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp17
4 files changed, 37 insertions, 18 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index bebdb9b6..c8e64c78 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -1551,16 +1551,22 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
_functionCall.expression().annotation().isPure &&
functionType->isPure();
+ bool allowDynamicTypes = false; // @TODO
if (!functionType)
{
m_errorReporter.typeError(_functionCall.location(), "Type is not callable");
_functionCall.annotation().type = make_shared<TupleType>();
return false;
}
- else if (functionType->returnParameterTypes().size() == 1)
- _functionCall.annotation().type = functionType->returnParameterTypes().front();
+
+ auto returnTypes =
+ allowDynamicTypes ?
+ functionType->returnParameterTypes() :
+ functionType->returnParameterTypesWithoutDynamicTypes();
+ if (returnTypes.size() == 1)
+ _functionCall.annotation().type = returnTypes.front();
else
- _functionCall.annotation().type = make_shared<TupleType>(functionType->returnParameterTypes());
+ _functionCall.annotation().type = make_shared<TupleType>(returnTypes);
if (auto functionName = dynamic_cast<Identifier const*>(&_functionCall.expression()))
{
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index b2881bea..41700e28 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -2311,6 +2311,18 @@ vector<string> FunctionType::parameterNames() const
return vector<string>(m_parameterNames.cbegin() + 1, m_parameterNames.cend());
}
+TypePointers FunctionType::returnParameterTypesWithoutDynamicTypes() const
+{
+ TypePointers returnParameterTypes = m_returnParameterTypes;
+
+ if (m_kind == Kind::External || m_kind == Kind::CallCode || m_kind == Kind::DelegateCall)
+ for (auto& param: returnParameterTypes)
+ if (param->isDynamicallySized() && !param->dataStoredIn(DataLocation::Storage))
+ param = make_shared<InaccessibleDynamicType>();
+
+ return returnParameterTypes;
+}
+
TypePointers FunctionType::parameterTypes() const
{
if (!bound())
@@ -2772,18 +2784,9 @@ FunctionTypePointer FunctionType::asMemberFunction(bool _inLibrary, bool _bound)
kind = Kind::DelegateCall;
}
- TypePointers returnParameterTypes = m_returnParameterTypes;
- if (kind != Kind::Internal)
- {
- // Alter dynamic types to be non-accessible.
- for (auto& param: returnParameterTypes)
- if (param->isDynamicallySized())
- param = make_shared<InaccessibleDynamicType>();
- }
-
return make_shared<FunctionType>(
parameterTypes,
- returnParameterTypes,
+ m_returnParameterTypes,
m_parameterNames,
m_returnParameterNames,
kind,
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index c20a025f..c930dd24 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -973,6 +973,9 @@ public:
TypePointers parameterTypes() const;
std::vector<std::string> parameterNames() const;
TypePointers const& returnParameterTypes() const { return m_returnParameterTypes; }
+ /// @returns the list of return parameter types. All dynamically-sized types (this excludes
+ /// storage pointers) are replaced by InaccessibleDynamicType instances.
+ TypePointers returnParameterTypesWithoutDynamicTypes() const;
std::vector<std::string> const& returnParameterNames() const { return m_returnParameterNames; }
/// @returns the "self" parameter type for a bound function
TypePointer const& selfType() const;
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index f50628ff..7d148c0c 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -139,8 +139,8 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
utils().popStackSlots(paramTypes.size() - 1);
}
unsigned retSizeOnStack = 0;
- solAssert(accessorType.returnParameterTypes().size() >= 1, "");
- auto const& returnTypes = accessorType.returnParameterTypes();
+ auto returnTypes = accessorType.returnParameterTypes();
+ solAssert(returnTypes.size() >= 1, "");
if (StructType const* structType = dynamic_cast<StructType const*>(returnType.get()))
{
// remove offset
@@ -1618,15 +1618,22 @@ void ExpressionCompiler::appendExternalFunctionCall(
m_context.experimentalFeatureActive(ExperimentalFeature::V050) &&
m_context.evmVersion().hasStaticCall();
+ bool allowDynamicTypes = false; // @TODO
unsigned retSize = 0;
+ TypePointers returnTypes;
if (returnSuccessCondition)
retSize = 0; // return value actually is success condition
+ else if (allowDynamicTypes)
+ returnTypes = _functionType.returnParameterTypes();
else
- for (auto const& retType: _functionType.returnParameterTypes())
+ {
+ returnTypes = _functionType.returnParameterTypesWithoutDynamicTypes();
+ for (auto const& retType: returnTypes)
{
solAssert(!retType->isDynamicallySized(), "Unable to return dynamic type from external call.");
retSize += retType->calldataEncodedSize();
}
+ }
// Evaluate arguments.
TypePointers argumentTypes;
@@ -1824,11 +1831,11 @@ void ExpressionCompiler::appendExternalFunctionCall(
utils().fetchFreeMemoryPointer();
m_context << Instruction::SUB << Instruction::MLOAD;
}
- else if (!_functionType.returnParameterTypes().empty())
+ else if (!returnTypes.empty())
{
utils().fetchFreeMemoryPointer();
bool memoryNeeded = false;
- for (auto const& retType: _functionType.returnParameterTypes())
+ for (auto const& retType: returnTypes)
{
utils().loadFromMemoryDynamic(*retType, false, true, true);
if (dynamic_cast<ReferenceType const*>(retType.get()))