aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/analysis
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-04-13 02:55:03 +0800
committerGitHub <noreply@github.com>2018-04-13 02:55:03 +0800
commit44416d1ac65b2cfae4bb15d39bc84b1a78211baa (patch)
tree7b8ee302e1c4f0604f29d2fe21a2d0393cc60d11 /libsolidity/analysis
parent7453ff0f3a94ce4ddce55cdbb77146dd75a01e1c (diff)
parent75b88286667690ffb4a5e079665ed8b70bcaeb87 (diff)
downloaddexon-solidity-44416d1ac65b2cfae4bb15d39bc84b1a78211baa.tar
dexon-solidity-44416d1ac65b2cfae4bb15d39bc84b1a78211baa.tar.gz
dexon-solidity-44416d1ac65b2cfae4bb15d39bc84b1a78211baa.tar.bz2
dexon-solidity-44416d1ac65b2cfae4bb15d39bc84b1a78211baa.tar.lz
dexon-solidity-44416d1ac65b2cfae4bb15d39bc84b1a78211baa.tar.xz
dexon-solidity-44416d1ac65b2cfae4bb15d39bc84b1a78211baa.tar.zst
dexon-solidity-44416d1ac65b2cfae4bb15d39bc84b1a78211baa.zip
Merge pull request #2980 from ethereum/abi-api
Add abi.encode and abi.encodePacked
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r--libsolidity/analysis/GlobalContext.cpp1
-rw-r--r--libsolidity/analysis/TypeChecker.cpp42
-rw-r--r--libsolidity/analysis/ViewPureChecker.cpp7
3 files changed, 39 insertions, 11 deletions
diff --git a/libsolidity/analysis/GlobalContext.cpp b/libsolidity/analysis/GlobalContext.cpp
index 6a858d36..ef1a59fe 100644
--- a/libsolidity/analysis/GlobalContext.cpp
+++ b/libsolidity/analysis/GlobalContext.cpp
@@ -35,6 +35,7 @@ namespace solidity
GlobalContext::GlobalContext():
m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{
+ make_shared<MagicVariableDeclaration>("abi", make_shared<MagicType>(MagicType::Kind::ABI)),
make_shared<MagicVariableDeclaration>("addmod", make_shared<FunctionType>(strings{"uint256", "uint256", "uint256"}, strings{"uint256"}, FunctionType::Kind::AddMod, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("assert", make_shared<FunctionType>(strings{"bool"}, strings{}, FunctionType::Kind::Assert, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("block", make_shared<MagicType>(MagicType::Kind::Block)),
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 8b57fc15..b95fee38 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -1688,7 +1688,19 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
}
}
- if (!functionType->takesArbitraryParameters() && parameterTypes.size() != arguments.size())
+ if (functionType->takesArbitraryParameters() && arguments.size() < parameterTypes.size())
+ {
+ solAssert(_functionCall.annotation().kind == FunctionCallKind::FunctionCall, "");
+ m_errorReporter.typeError(
+ _functionCall.location(),
+ "Need at least " +
+ toString(parameterTypes.size()) +
+ " arguments for function call, but provided only " +
+ toString(arguments.size()) +
+ "."
+ );
+ }
+ else if (!functionType->takesArbitraryParameters() && parameterTypes.size() != arguments.size())
{
bool isStructConstructorCall = _functionCall.annotation().kind == FunctionCallKind::StructConstructorCall;
@@ -1711,11 +1723,12 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
}
else if (isPositionalCall)
{
- // call by positional arguments
+ bool const abiEncodeV2 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::ABIEncoderV2);
+
for (size_t i = 0; i < arguments.size(); ++i)
{
auto const& argType = type(*arguments[i]);
- if (functionType->takesArbitraryParameters())
+ if (functionType->takesArbitraryParameters() && i >= parameterTypes.size())
{
bool errored = false;
if (auto t = dynamic_cast<RationalNumberType const*>(argType.get()))
@@ -1724,13 +1737,22 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
m_errorReporter.typeError(arguments[i]->location(), "Invalid rational number (too large or division by zero).");
errored = true;
}
- if (!errored && !(
- argType->mobileType() &&
- argType->mobileType()->interfaceType(false) &&
- argType->mobileType()->interfaceType(false)->encodingType() &&
- !(dynamic_cast<StructType const*>(argType->mobileType()->interfaceType(false)->encodingType().get()))
- ))
- m_errorReporter.typeError(arguments[i]->location(), "This type cannot be encoded.");
+ if (!errored)
+ {
+ TypePointer encodingType;
+ if (
+ argType->mobileType() &&
+ argType->mobileType()->interfaceType(false) &&
+ argType->mobileType()->interfaceType(false)->encodingType()
+ )
+ encodingType = argType->mobileType()->interfaceType(false)->encodingType();
+ // Structs are fine as long as ABIV2 is activated and we do not do packed encoding.
+ if (!encodingType || (
+ dynamic_cast<StructType const*>(encodingType.get()) &&
+ !(abiEncodeV2 && functionType->padArguments())
+ ))
+ m_errorReporter.typeError(arguments[i]->location(), "This type cannot be encoded.");
+ }
}
else if (!type(*arguments[i])->isImplicitlyConvertibleTo(*parameterTypes[i]))
m_errorReporter.typeError(
diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp
index 13c3ab68..d9843012 100644
--- a/libsolidity/analysis/ViewPureChecker.cpp
+++ b/libsolidity/analysis/ViewPureChecker.cpp
@@ -305,10 +305,15 @@ void ViewPureChecker::endVisit(MemberAccess const& _memberAccess)
mutability = StateMutability::View;
break;
case Type::Category::Magic:
+ {
// we can ignore the kind of magic and only look at the name of the member
- if (member != "data" && member != "sig" && member != "blockhash")
+ set<string> static const pureMembers{
+ "encode", "encodePacked", "encodeWithSelector", "encodeWithSignature", "data", "sig", "blockhash"
+ };
+ if (!pureMembers.count(member))
mutability = StateMutability::View;
break;
+ }
case Type::Category::Struct:
{
if (_memberAccess.expression().annotation().type->dataStoredIn(DataLocation::Storage))