Disallow the same yul variable occurring multiple times on the LHS of an assignment.

This commit is contained in:
Daniel Kirchner 2020-07-06 17:25:55 +02:00
parent 375cb09341
commit 70615a73a4
5 changed files with 32 additions and 0 deletions

View File

@ -21,6 +21,7 @@ Bugfixes:
* Type Checker: Do not disallow assigning to calldata variables.
* Wasm backend: Fix code generation for for-loops with pre statements.
* 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.