diff options
author | Daniel Kirchner <daniel@ekpyron.org> | 2018-07-05 00:34:24 +0800 |
---|---|---|
committer | Daniel Kirchner <daniel@ekpyron.org> | 2018-07-13 02:33:51 +0800 |
commit | fc370591f02d2bcfe52b62776a871b33e933bd34 (patch) | |
tree | 08101656cd0bef2da7a93fea9e3806e235a2acbd /libsolidity/analysis | |
parent | 5d8a8f726555361a78dac05a5413558f3f63f7f1 (diff) | |
download | dexon-solidity-fc370591f02d2bcfe52b62776a871b33e933bd34.tar.gz dexon-solidity-fc370591f02d2bcfe52b62776a871b33e933bd34.tar.zst dexon-solidity-fc370591f02d2bcfe52b62776a871b33e933bd34.zip |
Disallow multi variable declarations with mismatching number of values.
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 88 |
1 files changed, 16 insertions, 72 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 8ea0a4d7..e2e4d9c3 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1043,10 +1043,10 @@ namespace * @returns a suggested left-hand-side of a multi-variable declaration contairing * the variable declarations given in @a _decls. */ -string createTupleDecl(vector<VariableDeclaration const*> const& _decls) +string createTupleDecl(vector<ASTPointer<VariableDeclaration>> const& _decls) { vector<string> components; - for (VariableDeclaration const* decl: _decls) + for (ASTPointer<VariableDeclaration> const& decl: _decls) if (decl) components.emplace_back(decl->annotation().type->toString(false) + " " + decl->name()); else @@ -1058,9 +1058,9 @@ string createTupleDecl(vector<VariableDeclaration const*> const& _decls) return "(" + boost::algorithm::join(components, ", ") + ")"; } -bool typeCanBeExpressed(vector<VariableDeclaration const*> const& decls) +bool typeCanBeExpressed(vector<ASTPointer<VariableDeclaration>> const& decls) { - for (VariableDeclaration const* decl: decls) + for (ASTPointer<VariableDeclaration> const& decl: decls) { // skip empty tuples (they can be expressed of course) if (!decl) @@ -1080,7 +1080,6 @@ bool typeCanBeExpressed(vector<VariableDeclaration const*> const& decls) bool TypeChecker::visit(VariableDeclarationStatement const& _statement) { - bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); if (!_statement.initialValue()) { // No initial value is only permitted for single variables with specified type. @@ -1119,82 +1118,27 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) else valueTypes = TypePointers{type(*_statement.initialValue())}; - // Determine which component is assigned to which variable. - // If numbers do not match, fill up if variables begin or end empty (not both). - vector<VariableDeclaration const*>& assignments = _statement.annotation().assignments; - assignments.resize(valueTypes.size(), nullptr); vector<ASTPointer<VariableDeclaration>> const& variables = _statement.declarations(); if (variables.empty()) - { - if (!valueTypes.empty()) - m_errorReporter.fatalTypeError( - _statement.location(), - "Too many components (" + - toString(valueTypes.size()) + - ") in value for variable assignment (0) needed" - ); - } + // We already have an error for this in the SyntaxChecker. + solAssert(m_errorReporter.hasErrors(), ""); else if (valueTypes.size() != variables.size()) - { - if (v050) - m_errorReporter.fatalTypeError( - _statement.location(), - "Different number of components on the left hand side (" + - toString(variables.size()) + - ") than on the right hand side (" + - toString(valueTypes.size()) + - ")." - ); - else if (!variables.front() && !variables.back()) - m_errorReporter.fatalTypeError( - _statement.location(), - "Wildcard both at beginning and end of variable declaration list is only allowed " - "if the number of components is equal." - ); - else - m_errorReporter.warning( - _statement.location(), - "Different number of components on the left hand side (" + - toString(variables.size()) + - ") than on the right hand side (" + - toString(valueTypes.size()) + - ")." - ); - } - size_t minNumValues = variables.size(); - if (!variables.empty() && (!variables.back() || !variables.front())) - --minNumValues; - if (valueTypes.size() < minNumValues) - m_errorReporter.fatalTypeError( - _statement.location(), - "Not enough components (" + - toString(valueTypes.size()) + - ") in value to assign all variables (" + - toString(minNumValues) + ")." - ); - if (valueTypes.size() > variables.size() && variables.front() && variables.back()) - m_errorReporter.fatalTypeError( + m_errorReporter.typeError( _statement.location(), - "Too many components (" + + "Different number of components on the left hand side (" + + toString(variables.size()) + + ") than on the right hand side (" + toString(valueTypes.size()) + - ") in value for variable assignment (" + - toString(minNumValues) + - " needed)." + ")." ); - bool fillRight = !variables.empty() && (!variables.back() || variables.front()); - for (size_t i = 0; i < min(variables.size(), valueTypes.size()); ++i) - if (fillRight) - assignments[i] = variables[i].get(); - else - assignments[assignments.size() - i - 1] = variables[variables.size() - i - 1].get(); bool autoTypeDeductionNeeded = false; - for (size_t i = 0; i < assignments.size(); ++i) + for (size_t i = 0; i < min(variables.size(), valueTypes.size()); ++i) { - if (!assignments[i]) + if (!variables[i]) continue; - VariableDeclaration const& var = *assignments[i]; + VariableDeclaration const& var = *variables[i]; solAssert(!var.value(), "Value has to be tied to statement."); TypePointer const& valueComponentType = valueTypes[i]; solAssert(!!valueComponentType, ""); @@ -1284,7 +1228,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) if (autoTypeDeductionNeeded) { - if (!typeCanBeExpressed(assignments)) + if (!typeCanBeExpressed(variables)) m_errorReporter.syntaxError( _statement.location(), "Use of the \"var\" keyword is disallowed. " @@ -1294,7 +1238,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) m_errorReporter.syntaxError( _statement.location(), "Use of the \"var\" keyword is disallowed. " - "Use explicit declaration `" + createTupleDecl(assignments) + " = ...´ instead." + "Use explicit declaration `" + createTupleDecl(variables) + " = ...´ instead." ); } |