diff options
author | chriseth <chris@ethereum.org> | 2018-07-10 21:18:00 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-10 21:18:00 +0800 |
commit | d9c3b10b1c5ad5d9dffbaceb48cd99e7293a6c56 (patch) | |
tree | f7755f7c68f324eaa784abff71e8fd37747401df /libsolidity | |
parent | 5c404fcfac113d2e25f80b298e485099baa27fb8 (diff) | |
parent | 951b745bd9324c2b07049ab9565ed7c3438fcb89 (diff) | |
download | dexon-solidity-d9c3b10b1c5ad5d9dffbaceb48cd99e7293a6c56.tar.gz dexon-solidity-d9c3b10b1c5ad5d9dffbaceb48cd99e7293a6c56.tar.zst dexon-solidity-d9c3b10b1c5ad5d9dffbaceb48cd99e7293a6c56.zip |
Merge pull request #4465 from ethereum/tupleAssignment
Disallow tuple assignment with mismatching number of components.
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 20 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 20 |
2 files changed, 5 insertions, 35 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index ed7f05f7..20e423e6 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1337,7 +1337,6 @@ bool TypeChecker::visit(Conditional const& _conditional) bool TypeChecker::visit(Assignment const& _assignment) { - bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); requireLValue(_assignment.leftHandSide()); TypePointer t = type(_assignment.leftHandSide()); _assignment.annotation().type = t; @@ -1354,25 +1353,8 @@ bool TypeChecker::visit(Assignment const& _assignment) expectType(_assignment.rightHandSide(), *tupleType); // expectType does not cause fatal errors, so we have to check again here. - if (TupleType const* rhsType = dynamic_cast<TupleType const*>(type(_assignment.rightHandSide()).get())) - { + if (dynamic_cast<TupleType const*>(type(_assignment.rightHandSide()).get())) checkDoubleStorageAssignment(_assignment); - // @todo For 0.5.0, this code shoud move to TupleType::isImplicitlyConvertibleTo, - // but we cannot do it right now. - if (rhsType->components().size() != tupleType->components().size()) - { - string message = - "Different number of components on the left hand side (" + - toString(tupleType->components().size()) + - ") than on the right hand side (" + - toString(rhsType->components().size()) + - ")."; - if (v050) - m_errorReporter.typeError(_assignment.location(), message); - else - m_errorReporter.warning(_assignment.location(), message); - } - } } else if (t->category() == Type::Category::Mapping) { diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 1c4eb76e..23614e58 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -2238,25 +2238,13 @@ bool TupleType::isImplicitlyConvertibleTo(Type const& _other) const TypePointers const& targets = tupleType->components(); if (targets.empty()) return components().empty(); - if (components().size() != targets.size() && !targets.front() && !targets.back()) - return false; // (,a,) = (1,2,3,4) - unable to position `a` in the tuple. - size_t minNumValues = targets.size(); - if (!targets.back() || !targets.front()) - --minNumValues; // wildcards can also match 0 components - if (components().size() < minNumValues) + if (components().size() != targets.size()) return false; - if (components().size() > targets.size() && targets.front() && targets.back()) - return false; // larger source and no wildcard - bool fillRight = !targets.back() || targets.front(); - for (size_t i = 0; i < min(targets.size(), components().size()); ++i) - { - auto const& s = components()[fillRight ? i : components().size() - i - 1]; - auto const& t = targets[fillRight ? i : targets.size() - i - 1]; - if (!s && t) + for (size_t i = 0; i < targets.size(); ++i) + if (!components()[i] && targets[i]) return false; - else if (s && t && !s->isImplicitlyConvertibleTo(*t)) + else if (components()[i] && targets[i] && !components()[i]->isImplicitlyConvertibleTo(*targets[i])) return false; - } return true; } else |