Merge pull request #9321 from ethereum/multiYulAssign

Disallow the same yul variable occurring multiple times on the LHS of an assignment.
This commit is contained in:
chriseth 2020-07-07 11:07:05 +02:00 committed by GitHub
commit d72aae20aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 0 deletions

View File

@ -23,6 +23,7 @@ Bugfixes:
* Wasm backend: Fix code generation for for-loops with pre statements.
* Wasm backend: Properly support both ``i32.drop`` and ``i64.drop``, and remove ``drop``.
* Yul: Fix source location of variable multi-assignment.
* Yul: Disallow the same variable to occur multiple times on the left-hand side of an assignment.
### 0.6.10 (2020-06-11)

View File

@ -288,6 +288,8 @@ variables at the same time. For this, the number and types of the
values have to match.
If you want to assign the values returned from a function that has
multiple return parameters, you have to provide multiple variables.
The same variable may not occur multiple times on the left-hand side of
an assignment, e.g. ``x, x := f()`` is invalid.
.. code-block:: yul
@ -506,6 +508,8 @@ In variable declarations and assignments, the right-hand-side expression
variables on the left-hand-side.
This is the only situation where an expression evaluating
to more than one value is allowed.
The same variable name cannot occur more than once in the left-hand-side of
an assignment or variable declaration.
Expressions that are also statements (i.e. at the block level) have to
evaluate to zero values.

View File

@ -167,6 +167,17 @@ void AsmAnalyzer::operator()(Assignment const& _assignment)
size_t const numVariables = _assignment.variableNames.size();
yulAssert(numVariables >= 1, "");
set<YulString> variables;
for (auto const& _variableName: _assignment.variableNames)
if (!variables.insert(_variableName.name).second)
m_errorReporter.declarationError(
9005_error,
_assignment.location,
"Variable " +
_variableName.name.str() +
" occurs multiple times on the left-hand side of the assignment."
);
vector<YulString> types = std::visit(*this, *_assignment.value);
if (types.size() != numVariables)

View File

@ -0,0 +1,10 @@
{
function f() -> a, b {}
function g() -> a, b, c {}
let x, y
x, x := f()
y, x, y := g()
}
// ----
// DeclarationError 9005: (70-81): Variable x occurs multiple times on the left-hand side of the assignment.
// DeclarationError 9005: (84-98): Variable y occurs multiple times on the left-hand side of the assignment.

View File

@ -0,0 +1,6 @@
{
function f() -> a, b {}
let x, x := f()
}
// ----
// DeclarationError 1395: (30-45): Variable name x already taken in this scope.