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. * Type Checker: Do not disallow assigning to calldata variables.
* Wasm backend: Fix code generation for for-loops with pre statements. * Wasm backend: Fix code generation for for-loops with pre statements.
* Yul: Fix source location of variable multi-assignment. * 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) ### 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. values have to match.
If you want to assign the values returned from a function that has If you want to assign the values returned from a function that has
multiple return parameters, you have to provide multiple variables. 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 .. code-block:: yul
@ -506,6 +508,8 @@ In variable declarations and assignments, the right-hand-side expression
variables on the left-hand-side. variables on the left-hand-side.
This is the only situation where an expression evaluating This is the only situation where an expression evaluating
to more than one value is allowed. 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 Expressions that are also statements (i.e. at the block level) have to
evaluate to zero values. evaluate to zero values.

View File

@ -167,6 +167,17 @@ void AsmAnalyzer::operator()(Assignment const& _assignment)
size_t const numVariables = _assignment.variableNames.size(); size_t const numVariables = _assignment.variableNames.size();
yulAssert(numVariables >= 1, ""); 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); vector<YulString> types = std::visit(*this, *_assignment.value);
if (types.size() != numVariables) 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.