aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/ast
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/ast')
-rw-r--r--libsolidity/ast/AST.cpp28
-rw-r--r--libsolidity/ast/AST.h33
-rw-r--r--libsolidity/ast/ASTAnnotations.h7
-rw-r--r--libsolidity/ast/ASTJsonConverter.cpp37
-rw-r--r--libsolidity/ast/ASTJsonConverter.h1
-rw-r--r--libsolidity/ast/ExperimentalFeatures.h35
-rw-r--r--libsolidity/ast/Types.cpp139
-rw-r--r--libsolidity/ast/Types.h14
8 files changed, 190 insertions, 104 deletions
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp
index 724a908f..1d68231e 100644
--- a/libsolidity/ast/AST.cpp
+++ b/libsolidity/ast/AST.cpp
@@ -84,13 +84,35 @@ SourceUnitAnnotation& SourceUnit::annotation() const
return dynamic_cast<SourceUnitAnnotation&>(*m_annotation);
}
-string Declaration::sourceUnitName() const
+set<SourceUnit const*> SourceUnit::referencedSourceUnits(bool _recurse, set<SourceUnit const*> _skipList) const
+{
+ set<SourceUnit const*> sourceUnits;
+ for (ImportDirective const* importDirective: filteredNodes<ImportDirective>(nodes()))
+ {
+ auto const& sourceUnit = importDirective->annotation().sourceUnit;
+ if (!_skipList.count(sourceUnit))
+ {
+ _skipList.insert(sourceUnit);
+ sourceUnits.insert(sourceUnit);
+ if (_recurse)
+ sourceUnits += sourceUnit->referencedSourceUnits(true, _skipList);
+ }
+ }
+ return sourceUnits;
+}
+
+SourceUnit const& Declaration::sourceUnit() const
{
solAssert(!!m_scope, "");
ASTNode const* scope = m_scope;
while (dynamic_cast<Declaration const*>(scope) && dynamic_cast<Declaration const*>(scope)->m_scope)
scope = dynamic_cast<Declaration const*>(scope)->m_scope;
- return dynamic_cast<SourceUnit const&>(*scope).annotation().path;
+ return dynamic_cast<SourceUnit const&>(*scope);
+}
+
+string Declaration::sourceUnitName() const
+{
+ return sourceUnit().annotation().path;
}
ImportAnnotation& ImportDirective::annotation() const
@@ -140,7 +162,7 @@ FunctionDefinition const* ContractDefinition::fallbackFunction() const
{
for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
for (FunctionDefinition const* f: contract->definedFunctions())
- if (f->name().empty())
+ if (f->isFallback())
return f;
return nullptr;
}
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h
index 81ddc754..bdf20e81 100644
--- a/libsolidity/ast/AST.h
+++ b/libsolidity/ast/AST.h
@@ -136,6 +136,9 @@ public:
std::vector<ASTPointer<ASTNode>> nodes() const { return m_nodes; }
+ /// @returns a set of referenced SourceUnits. Recursively if @a _recurse is true.
+ std::set<SourceUnit const*> referencedSourceUnits(bool _recurse = false, std::set<SourceUnit const*> _skipList = std::set<SourceUnit const*>()) const;
+
private:
std::vector<ASTPointer<ASTNode>> m_nodes;
};
@@ -149,6 +152,24 @@ public:
/// Visibility ordered from restricted to unrestricted.
enum class Visibility { Default, Private, Internal, Public, External };
+ static std::string visibilityToString(Declaration::Visibility _visibility)
+ {
+ switch(_visibility)
+ {
+ case Declaration::Visibility::Public:
+ return "public";
+ case Declaration::Visibility::Internal:
+ return "internal";
+ case Declaration::Visibility::Private:
+ return "private";
+ case Declaration::Visibility::External:
+ return "external";
+ default:
+ solAssert(false, "Invalid visibility specifier.");
+ }
+ return std::string();
+ }
+
Declaration(
SourceLocation const& _location,
ASTPointer<ASTString> const& _name,
@@ -168,6 +189,9 @@ public:
ASTNode const* scope() const { return m_scope; }
void setScope(ASTNode const* _scope) { m_scope = _scope; }
+ /// @returns the source unit this declaration is present in.
+ SourceUnit const& sourceUnit() const;
+
/// @returns the source name this declaration is present in.
/// Can be combined with annotation().canonicalName to form a globally unique name.
std::string sourceUnitName() const;
@@ -583,6 +607,7 @@ public:
virtual void accept(ASTConstVisitor& _visitor) const override;
bool isConstructor() const { return m_isConstructor; }
+ bool isFallback() const { return name().empty(); }
bool isDeclaredConst() const { return m_isDeclaredConst; }
bool isPayable() const { return m_isPayable; }
std::vector<ASTPointer<ModifierInvocation>> const& modifiers() const { return m_functionModifiers; }
@@ -590,9 +615,9 @@ public:
Block const& body() const { solAssert(m_body, ""); return *m_body; }
virtual bool isVisibleInContract() const override
{
- return Declaration::isVisibleInContract() && !isConstructor() && !name().empty();
+ return Declaration::isVisibleInContract() && !isConstructor() && !isFallback();
}
- virtual bool isPartOfExternalInterface() const override { return isPublic() && !m_isConstructor && !name().empty(); }
+ virtual bool isPartOfExternalInterface() const override { return isPublic() && !isConstructor() && !isFallback(); }
/// @returns the external signature of the function
/// That consists of the name of the function followed by the types of the
@@ -791,11 +816,11 @@ public:
Declaration(SourceLocation(), std::make_shared<ASTString>(_name)), m_type(_type) {}
virtual void accept(ASTVisitor&) override
{
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("MagicVariableDeclaration used inside real AST."));
+ solAssert(false, "MagicVariableDeclaration used inside real AST.");
}
virtual void accept(ASTConstVisitor&) const override
{
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("MagicVariableDeclaration used inside real AST."));
+ solAssert(false, "MagicVariableDeclaration used inside real AST.");
}
virtual TypePointer type() const override { return m_type; }
diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h
index 45a6dd1a..fd9efb4d 100644
--- a/libsolidity/ast/ASTAnnotations.h
+++ b/libsolidity/ast/ASTAnnotations.h
@@ -23,6 +23,7 @@
#pragma once
#include <libsolidity/ast/ASTForward.h>
+#include <libsolidity/ast/ExperimentalFeatures.h>
#include <map>
#include <memory>
@@ -61,6 +62,8 @@ struct SourceUnitAnnotation: ASTAnnotation
std::string path;
/// The exported symbols (all global symbols).
std::map<ASTString, std::vector<Declaration const*>> exportedSymbols;
+ /// Experimental features.
+ std::set<ExperimentalFeature> experimentalFeatures;
};
struct ImportAnnotation: ASTAnnotation
@@ -79,8 +82,8 @@ struct TypeDeclarationAnnotation: ASTAnnotation
struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, DocumentedAnnotation
{
- /// Whether all functions are implemented.
- bool isFullyImplemented = true;
+ /// List of functions without a body. Can also contain functions from base classes.
+ std::vector<FunctionDefinition const*> unimplementedFunctions;
/// List of all (direct and indirect) base contracts in order from derived to
/// base, including the contract itself.
std::vector<ContractDefinition const*> linearizedBaseContracts;
diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp
index a90debb2..abee55ee 100644
--- a/libsolidity/ast/ASTJsonConverter.cpp
+++ b/libsolidity/ast/ASTJsonConverter.cpp
@@ -253,7 +253,7 @@ bool ASTJsonConverter::visit(ContractDefinition const& _node)
make_pair("name", _node.name()),
make_pair("documentation", _node.documentation() ? Json::Value(*_node.documentation()) : Json::nullValue),
make_pair("contractKind", contractKind(_node.contractKind())),
- make_pair("fullyImplemented", _node.annotation().isFullyImplemented),
+ make_pair("fullyImplemented", _node.annotation().unimplementedFunctions.empty()),
make_pair("linearizedBaseContracts", getContainerIds(_node.annotation().linearizedBaseContracts)),
make_pair("baseContracts", toJson(_node.baseContracts())),
make_pair("contractDependencies", getContainerIds(_node.annotation().contractDependencies)),
@@ -285,7 +285,7 @@ bool ASTJsonConverter::visit(StructDefinition const& _node)
{
setJsonNode(_node, "StructDefinition", {
make_pair("name", _node.name()),
- make_pair("visibility", visibility(_node.visibility())),
+ make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
make_pair("canonicalName", _node.annotation().canonicalName),
make_pair("members", toJson(_node.members())),
make_pair("scope", idOrNull(_node.scope()))
@@ -325,7 +325,7 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node)
make_pair("name", _node.name()),
make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.isDeclaredConst()),
make_pair("payable", _node.isPayable()),
- make_pair("visibility", visibility(_node.visibility())),
+ make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
make_pair("parameters", toJson(_node.parameterList())),
make_pair("isConstructor", _node.isConstructor()),
make_pair("returnParameters", toJson(*_node.returnParameterList())),
@@ -346,7 +346,7 @@ bool ASTJsonConverter::visit(VariableDeclaration const& _node)
make_pair("constant", _node.isConstant()),
make_pair("stateVariable", _node.isStateVariable()),
make_pair("storageLocation", location(_node.referenceLocation())),
- make_pair("visibility", visibility(_node.visibility())),
+ make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
make_pair("value", _node.value() ? toJson(*_node.value()) : Json::nullValue),
make_pair("scope", idOrNull(_node.scope())),
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type))
@@ -361,7 +361,7 @@ bool ASTJsonConverter::visit(ModifierDefinition const& _node)
{
setJsonNode(_node, "ModifierDefinition", {
make_pair("name", _node.name()),
- make_pair("visibility", visibility(_node.visibility())),
+ make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
make_pair("parameters", toJson(_node.parameterList())),
make_pair("body", toJson(_node.body()))
});
@@ -418,7 +418,7 @@ bool ASTJsonConverter::visit(FunctionTypeName const& _node)
{
setJsonNode(_node, "FunctionTypeName", {
make_pair("payable", _node.isPayable()),
- make_pair("visibility", visibility(_node.visibility())),
+ make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.isDeclaredConst()),
make_pair("parameterTypes", toJson(*_node.parameterTypeList())),
make_pair("returnParameterTypes", toJson(*_node.returnParameterTypeList())),
@@ -730,23 +730,6 @@ void ASTJsonConverter::endVisit(EventDefinition const&)
m_inEvent = false;
}
-string ASTJsonConverter::visibility(Declaration::Visibility const& _visibility)
-{
- switch (_visibility)
- {
- case Declaration::Visibility::Private:
- return "private";
- case Declaration::Visibility::Internal:
- return "internal";
- case Declaration::Visibility::Public:
- return "public";
- case Declaration::Visibility::External:
- return "external";
- default:
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown declaration visibility."));
- }
-}
-
string ASTJsonConverter::location(VariableDeclaration::Location _location)
{
switch (_location)
@@ -758,7 +741,7 @@ string ASTJsonConverter::location(VariableDeclaration::Location _location)
case VariableDeclaration::Location::Memory:
return "memory";
default:
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown declaration location."));
+ solAssert(false, "Unknown declaration location.");
}
}
@@ -773,7 +756,7 @@ string ASTJsonConverter::contractKind(ContractDefinition::ContractKind _kind)
case ContractDefinition::ContractKind::Library:
return "library";
default:
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of contract."));
+ solAssert(false, "Unknown kind of contract.");
}
}
@@ -788,7 +771,7 @@ string ASTJsonConverter::functionCallKind(FunctionCallKind _kind)
case FunctionCallKind::StructConstructorCall:
return "structConstructorCall";
default:
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of function call ."));
+ solAssert(false, "Unknown kind of function call.");
}
}
@@ -804,7 +787,7 @@ string ASTJsonConverter::literalTokenKind(Token::Value _token)
case dev::solidity::Token::FalseLiteral:
return "bool";
default:
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of literal token."));
+ solAssert(false, "Unknown kind of literal token.");
}
}
diff --git a/libsolidity/ast/ASTJsonConverter.h b/libsolidity/ast/ASTJsonConverter.h
index 27114c2a..70e260db 100644
--- a/libsolidity/ast/ASTJsonConverter.h
+++ b/libsolidity/ast/ASTJsonConverter.h
@@ -128,7 +128,6 @@ private:
return _node ? toJson(*_node) : Json::nullValue;
}
Json::Value inlineAssemblyIdentifierToJson(std::pair<assembly::Identifier const* , InlineAssemblyAnnotation::ExternalIdentifierInfo> _info);
- std::string visibility(Declaration::Visibility const& _visibility);
std::string location(VariableDeclaration::Location _location);
std::string contractKind(ContractDefinition::ContractKind _kind);
std::string functionCallKind(FunctionCallKind _kind);
diff --git a/libsolidity/ast/ExperimentalFeatures.h b/libsolidity/ast/ExperimentalFeatures.h
new file mode 100644
index 00000000..b0a07142
--- /dev/null
+++ b/libsolidity/ast/ExperimentalFeatures.h
@@ -0,0 +1,35 @@
+/*
+ This file is part of solidity.
+
+ 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.
+
+ 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 solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * List of experimental features.
+ */
+
+#pragma once
+
+#include <map>
+
+namespace dev
+{
+namespace solidity
+{
+
+enum class ExperimentalFeature {};
+
+static const std::map<std::string, ExperimentalFeature> ExperimentalFeatureNames = {};
+
+}
+}
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index bcfccc3e..a66ccda5 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -211,9 +211,10 @@ TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type)
return make_shared<ArrayType>(DataLocation::Storage, true);
//no types found
default:
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment(
+ solAssert(
+ false,
"Unable to convert elementary typename " + _type.toString() + " to type."
- ));
+ );
}
}
@@ -476,7 +477,7 @@ MemberList::MemberMap IntegerType::nativeMembers(ContractDefinition const*) cons
if (isAddress())
return {
{"balance", make_shared<IntegerType >(256)},
- {"call", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::Bare, true, false, true)},
+ {"call", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareCall, true, false, true)},
{"callcode", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareCallCode, true, false, true)},
{"delegatecall", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareDelegateCall, true)},
{"send", make_shared<FunctionType>(strings{"uint"}, strings{"bool"}, FunctionType::Kind::Send)},
@@ -524,19 +525,20 @@ bool FixedPointType::isExplicitlyConvertibleTo(Type const& _convertTo) const
TypePointer FixedPointType::unaryOperatorResult(Token::Value _operator) const
{
- // "delete" is ok for all fixed types
- if (_operator == Token::Delete)
+ switch(_operator)
+ {
+ case Token::Delete:
+ // "delete" is ok for all fixed types
return make_shared<TupleType>();
- // for fixed, we allow +, -, ++ and --
- else if (
- _operator == Token::Add ||
- _operator == Token::Sub ||
- _operator == Token::Inc ||
- _operator == Token::Dec
- )
+ case Token::Add:
+ case Token::Sub:
+ case Token::Inc:
+ case Token::Dec:
+ // for fixed, we allow +, -, ++ and --
return shared_from_this();
- else
+ default:
return TypePointer();
+ }
}
bool FixedPointType::operator==(Type const& _other) const
@@ -1176,7 +1178,7 @@ u256 BoolType::literalValue(Literal const* _literal) const
else if (_literal->token() == Token::FalseLiteral)
return u256(0);
else
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Bool type constructed from non-boolean literal."));
+ solAssert(false, "Bool type constructed from non-boolean literal.");
}
TypePointer BoolType::unaryOperatorResult(Token::Value _operator) const
@@ -1407,6 +1409,11 @@ unsigned ArrayType::calldataEncodedSize(bool _padded) const
return unsigned(size);
}
+bool ArrayType::isDynamicallyEncoded() const
+{
+ return isDynamicallySized() || baseType()->isDynamicallyEncoded();
+}
+
u256 ArrayType::storageSize() const
{
if (isDynamicallySized())
@@ -1709,6 +1716,11 @@ unsigned StructType::calldataEncodedSize(bool _padded) const
return size;
}
+bool StructType::isDynamicallyEncoded() const
+{
+ solAssert(false, "Structs are not yet supported in the ABI.");
+}
+
u256 StructType::memorySize() const
{
u256 size;
@@ -1938,10 +1950,7 @@ string TupleType::toString(bool _short) const
u256 TupleType::storageSize() const
{
- BOOST_THROW_EXCEPTION(
- InternalCompilerError() <<
- errinfo_comment("Storage size of non-storable tuple type requested.")
- );
+ solAssert(false, "Storage size of non-storable tuple type requested.");
}
unsigned TupleType::sizeOnStack() const
@@ -2180,7 +2189,7 @@ string FunctionType::identifier() const
case Kind::External: id += "external"; break;
case Kind::CallCode: id += "callcode"; break;
case Kind::DelegateCall: id += "delegatecall"; break;
- case Kind::Bare: id += "bare"; break;
+ case Kind::BareCall: id += "barecall"; break;
case Kind::BareCallCode: id += "barecallcode"; break;
case Kind::BareDelegateCall: id += "baredelegatecall"; break;
case Kind::Creation: id += "creation"; break;
@@ -2212,6 +2221,8 @@ string FunctionType::identifier() const
}
if (isConstant())
id += "_constant";
+ if (isPayable())
+ id += "_payable";
id += identifierList(m_parameterTypes) + "returns" + identifierList(m_returnParameterTypes);
if (m_gasSet)
id += "gas";
@@ -2226,23 +2237,22 @@ bool FunctionType::operator==(Type const& _other) const
{
if (_other.category() != category())
return false;
- FunctionType const& other = dynamic_cast<FunctionType const&>(_other);
- if (m_kind != other.m_kind)
- return false;
- if (m_isConstant != other.isConstant())
+ FunctionType const& other = dynamic_cast<FunctionType const&>(_other);
+ if (
+ m_kind != other.m_kind ||
+ m_isConstant != other.isConstant() ||
+ m_isPayable != other.isPayable() ||
+ m_parameterTypes.size() != other.m_parameterTypes.size() ||
+ m_returnParameterTypes.size() != other.m_returnParameterTypes.size()
+ )
return false;
- if (m_parameterTypes.size() != other.m_parameterTypes.size() ||
- m_returnParameterTypes.size() != other.m_returnParameterTypes.size())
- return false;
auto typeCompare = [](TypePointer const& _a, TypePointer const& _b) -> bool { return *_a == *_b; };
-
- if (!equal(m_parameterTypes.cbegin(), m_parameterTypes.cend(),
- other.m_parameterTypes.cbegin(), typeCompare))
- return false;
- if (!equal(m_returnParameterTypes.cbegin(), m_returnParameterTypes.cend(),
- other.m_returnParameterTypes.cbegin(), typeCompare))
+ if (
+ !equal(m_parameterTypes.cbegin(), m_parameterTypes.cend(), other.m_parameterTypes.cbegin(), typeCompare) ||
+ !equal(m_returnParameterTypes.cbegin(), m_returnParameterTypes.cend(), other.m_returnParameterTypes.cbegin(), typeCompare)
+ )
return false;
//@todo this is ugly, but cannot be prevented right now
if (m_gasSet != other.m_gasSet || m_valueSet != other.m_valueSet)
@@ -2323,9 +2333,7 @@ u256 FunctionType::storageSize() const
if (m_kind == Kind::External || m_kind == Kind::Internal)
return 1;
else
- BOOST_THROW_EXCEPTION(
- InternalCompilerError()
- << errinfo_comment("Storage size of non-storable function type requested."));
+ solAssert(false, "Storage size of non-storable function type requested.");
}
unsigned FunctionType::storageBytes() const
@@ -2335,9 +2343,7 @@ unsigned FunctionType::storageBytes() const
else if (m_kind == Kind::Internal)
return 8; // it should really not be possible to create larger programs
else
- BOOST_THROW_EXCEPTION(
- InternalCompilerError()
- << errinfo_comment("Storage size of non-storable function type requested."));
+ solAssert(false, "Storage size of non-storable function type requested.");
}
unsigned FunctionType::sizeOnStack() const
@@ -2350,14 +2356,26 @@ unsigned FunctionType::sizeOnStack() const
}
unsigned size = 0;
- if (kind == Kind::External || kind == Kind::CallCode || kind == Kind::DelegateCall)
+
+ switch(kind)
+ {
+ case Kind::External:
+ case Kind::CallCode:
+ case Kind::DelegateCall:
size = 2;
- else if (kind == Kind::Bare || kind == Kind::BareCallCode || kind == Kind::BareDelegateCall)
- size = 1;
- else if (kind == Kind::Internal)
- size = 1;
- else if (kind == Kind::ArrayPush || kind == Kind::ByteArrayPush)
+ break;
+ case Kind::BareCall:
+ case Kind::BareCallCode:
+ case Kind::BareDelegateCall:
+ case Kind::Internal:
+ case Kind::ArrayPush:
+ case Kind::ByteArrayPush:
size = 1;
+ break;
+ default:
+ break;
+ }
+
if (m_gasSet)
size++;
if (m_valueSet)
@@ -2395,10 +2413,15 @@ FunctionTypePointer FunctionType::interfaceFunctionType() const
return FunctionTypePointer();
return make_shared<FunctionType>(
- paramTypes, retParamTypes,
- m_parameterNames, m_returnParameterNames,
- m_kind, m_arbitraryParameters,
- m_declaration, m_isConstant, m_isPayable
+ paramTypes,
+ retParamTypes,
+ m_parameterNames,
+ m_returnParameterNames,
+ m_kind,
+ m_arbitraryParameters,
+ m_declaration,
+ m_isConstant,
+ m_isPayable
);
}
@@ -2408,10 +2431,7 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con
{
case Kind::External:
case Kind::Creation:
- case Kind::ECRecover:
- case Kind::SHA256:
- case Kind::RIPEMD160:
- case Kind::Bare:
+ case Kind::BareCall:
case Kind::BareCallCode:
case Kind::BareDelegateCall:
{
@@ -2515,7 +2535,7 @@ bool FunctionType::isBareCall() const
{
switch (m_kind)
{
- case Kind::Bare:
+ case Kind::BareCall:
case Kind::BareCallCode:
case Kind::BareDelegateCall:
case Kind::ECRecover:
@@ -2530,6 +2550,7 @@ bool FunctionType::isBareCall() const
string FunctionType::externalSignature() const
{
solAssert(m_declaration != nullptr, "External signature of function needs declaration");
+ solAssert(!m_declaration->name().empty(), "Fallback function has no signature.");
bool _inLibrary = dynamic_cast<ContractDefinition const&>(*m_declaration->scope()).isLibrary();
@@ -2695,9 +2716,7 @@ bool TypeType::operator==(Type const& _other) const
u256 TypeType::storageSize() const
{
- BOOST_THROW_EXCEPTION(
- InternalCompilerError()
- << errinfo_comment("Storage size of non-storable type type requested."));
+ solAssert(false, "Storage size of non-storable type type requested.");
}
unsigned TypeType::sizeOnStack() const
@@ -2764,9 +2783,7 @@ ModifierType::ModifierType(const ModifierDefinition& _modifier)
u256 ModifierType::storageSize() const
{
- BOOST_THROW_EXCEPTION(
- InternalCompilerError()
- << errinfo_comment("Storage size of non-storable type type requested."));
+ solAssert(false, "Storage size of non-storable type type requested.");
}
string ModifierType::identifier() const
@@ -2875,7 +2892,7 @@ MemberList::MemberMap MagicType::nativeMembers(ContractDefinition const*) const
{"gasprice", make_shared<IntegerType>(256)}
});
default:
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of magic."));
+ solAssert(false, "Unknown kind of magic.");
}
}
@@ -2890,6 +2907,6 @@ string MagicType::toString(bool) const
case Kind::Transaction:
return "tx";
default:
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of magic."));
+ solAssert(false, "Unknown kind of magic.");
}
}
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index 3d7dad16..8c9232c6 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -187,6 +187,7 @@ public:
/// @returns number of bytes used by this type when encoded for CALL. If it is a dynamic type,
/// returns the size of the pointer (usually 32). Returns 0 if the type cannot be encoded
/// in calldata.
+ /// @note: This should actually not be called on types, where isDynamicallyEncoded returns true.
/// If @a _padded then it is assumed that each element is padded to a multiple of 32 bytes.
virtual unsigned calldataEncodedSize(bool _padded) const { (void)_padded; return 0; }
/// @returns the size of this data type in bytes when stored in memory. For memory-reference
@@ -194,8 +195,10 @@ public:
virtual unsigned memoryHeadSize() const { return calldataEncodedSize(); }
/// Convenience version of @see calldataEncodedSize(bool)
unsigned calldataEncodedSize() const { return calldataEncodedSize(true); }
- /// @returns true if the type is dynamically encoded in calldata
+ /// @returns true if the type is a dynamic array
virtual bool isDynamicallySized() const { return false; }
+ /// @returns true if the type is dynamically encoded in the ABI
+ virtual bool isDynamicallyEncoded() const { return false; }
/// @returns the number of storage slots required to hold this value in storage.
/// For dynamically "allocated" types, it returns the size of the statically allocated head,
virtual u256 storageSize() const { return 1; }
@@ -245,10 +248,7 @@ public:
virtual std::string canonicalName(bool /*_addDataLocation*/) const { return toString(true); }
virtual u256 literalValue(Literal const*) const
{
- BOOST_THROW_EXCEPTION(
- InternalCompilerError() <<
- errinfo_comment("Literal value requested for type without literals.")
- );
+ solAssert(false, "Literal value requested for type without literals.");
}
/// @returns a (simpler) type that is encoded in the same way for external function calls.
@@ -612,6 +612,7 @@ public:
virtual bool operator==(const Type& _other) const override;
virtual unsigned calldataEncodedSize(bool _padded) const override;
virtual bool isDynamicallySized() const override { return m_hasDynamicLength; }
+ virtual bool isDynamicallyEncoded() const override;
virtual u256 storageSize() const override;
virtual bool canLiveOutsideStorage() const override { return m_baseType->canLiveOutsideStorage(); }
virtual unsigned sizeOnStack() const override;
@@ -726,6 +727,7 @@ public:
virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual unsigned calldataEncodedSize(bool _padded) const override;
+ virtual bool isDynamicallyEncoded() const override;
u256 memorySize() const;
virtual u256 storageSize() const override;
virtual bool canLiveOutsideStorage() const override { return true; }
@@ -841,7 +843,7 @@ public:
External, ///< external call using CALL
CallCode, ///< external call using CALLCODE, i.e. not exchanging the storage
DelegateCall, ///< external call using DELEGATECALL, i.e. not exchanging the storage
- Bare, ///< CALL without function hash
+ BareCall, ///< CALL without function hash
BareCallCode, ///< CALLCODE without function hash
BareDelegateCall, ///< DELEGATECALL without function hash
Creation, ///< external call using CREATE