aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md3
-rw-r--r--docs/abi-spec.rst100
-rw-r--r--docs/contracts.rst1
-rw-r--r--docs/control-structures.rst99
-rw-r--r--libsolidity/analysis/DeclarationContainer.h2
-rw-r--r--libsolidity/analysis/NameAndTypeResolver.cpp20
-rw-r--r--libsolidity/analysis/NameAndTypeResolver.h4
-rw-r--r--libsolidity/analysis/ReferencesResolver.cpp33
-rw-r--r--libsolidity/analysis/SyntaxChecker.cpp2
-rw-r--r--test/compilationTests/corion/provider.sol6
-rw-r--r--test/compilationTests/stringutils/strings.sol5
-rw-r--r--test/libsolidity/SMTChecker.cpp16
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp2
-rw-r--r--test/libsolidity/syntaxTests/double_variable_declaration.sol5
-rw-r--r--test/libsolidity/syntaxTests/double_variable_declaration_050.sol11
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_return_parameters_with_names.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol5
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol2
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables050.sol7
-rw-r--r--test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationScoping.sol4
-rw-r--r--test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationScoping2.sol8
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/137_external_visibility.sol2
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/448_no_unused_dec_after_use.sol6
-rw-r--r--test/libsolidity/syntaxTests/parsing/conditional_with_assignment.sol7
-rw-r--r--test/libsolidity/syntaxTests/parsing/function_type_in_struct.sol3
-rw-r--r--test/libsolidity/syntaxTests/parsing/while_loop.sol8
-rw-r--r--test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope.sol3
-rw-r--r--test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_050.sol10
-rw-r--r--test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation.sol3
-rw-r--r--test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation_050.sol10
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping.sol3
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_activation.sol3
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_activation_old.sol2
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_for.sol1
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_for2.sol1
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_for3.sol3
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_for_decl_in_body.sol3
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_old.sol2
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_self_use.sol2
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_self_use_050.sol8
40 files changed, 193 insertions, 227 deletions
diff --git a/Changelog.md b/Changelog.md
index 3e63108e..07b74ddc 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -16,15 +16,18 @@ Breaking Changes:
``implements``, ``macro``, ``mutable``, ``override``, ``partial``, ``promise``, ``reference``, ``sealed``,
``sizeof``, ``supports``, ``typedef`` and ``unchecked``.
* General: Remove assembly instruction aliases ``sha3`` and ``suicide``
+ * General: C99-style scoping rules are enforced now. This was already the case in the experimental 0.5.0 mode.
* Optimizer: Remove the no-op ``PUSH1 0 NOT AND`` sequence.
* Parser: Disallow trailing dots that are not followed by a number.
* Type Checker: Disallow arithmetic operations for boolean variables.
* Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size.
* Remove obsolete ``std`` directory from the Solidity repository. This means accessing ``https://github.com/ethereum/soldity/blob/develop/std/*.sol`` (or ``https://github.com/ethereum/solidity/std/*.sol`` in Remix) will not be possible.
+ * Syntax Checker: Named return values in function types are an error.
Language Features:
* General: Allow appending ``calldata`` keyword to types, to explicitly specify data location for arguments of external functions.
* General: Support ``pop()`` for storage arrays.
+ * General: Scoping rules now follow the C99-style.
Compiler Features:
* Type Checker: Show named argument in case of error.
diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst
index 856284db..2fb207c7 100644
--- a/docs/abi-spec.rst
+++ b/docs/abi-spec.rst
@@ -277,6 +277,106 @@ All together, the encoding is (newline after function selector and each 32-bytes
000000000000000000000000000000000000000000000000000000000000000d
48656c6c6f2c20776f726c642100000000000000000000000000000000000000
+Let us apply the same principle to encode the data for a function with a signature ``g(uint[][],string[])`` with values ``([[1, 2], [3]], ["one", "two", "three"])`` but start from the most atomic parts of the encoding:
+
+First we encode the length and data of the first embeded dynamic array ``[1, 2]`` of the first root array ``[[1, 2], [3]]``:
+
+ - ``0x0000000000000000000000000000000000000000000000000000000000000002`` (number of elements in the first array, 2; the elements themselves are ``1`` and ``2``)
+ - ``0x0000000000000000000000000000000000000000000000000000000000000001`` (first element)
+ - ``0x0000000000000000000000000000000000000000000000000000000000000002`` (second element)
+
+Then we encode the length and data of the second embeded dynamic array ``[3]`` of the first root array ``[[1, 2], [3]]``:
+
+ - ``0x0000000000000000000000000000000000000000000000000000000000000001`` (number of elements in the second array, 1; the element is ``3``)
+ - ``0x0000000000000000000000000000000000000000000000000000000000000003`` (first element)
+
+Then we need to find the offsets ``a`` and ``b`` for their respective dynamic arrays ``[1, 2]`` and ``[3]``. To calculate the offsets we can take a look at the encoded data of the first root array ``[[1, 2], [3]]`` enumerating each line in the encoding:
+
+::
+
+ 0 - a - offset of [1, 2]
+ 1 - b - offset of [3]
+ 2 - 0000000000000000000000000000000000000000000000000000000000000002 - count for [1, 2]
+ 3 - 0000000000000000000000000000000000000000000000000000000000000001 - encoding of 1
+ 4 - 0000000000000000000000000000000000000000000000000000000000000002 - encoding of 2
+ 5 - 0000000000000000000000000000000000000000000000000000000000000001 - count for [3]
+ 6 - 0000000000000000000000000000000000000000000000000000000000000003 - encoding of 3
+
+Offset ``a`` points to the start of the content of the array ``[1, 2]`` which is line 2 (64 bytes); thus ``a = 0x0000000000000000000000000000000000000000000000000000000000000040``.
+
+Offset ``b`` points to the start of the content of the array ``[3]`` which is line 5 (160 bytes); thus ``b = 0x00000000000000000000000000000000000000000000000000000000000000a0``.
+
+
+Then we encode the embeded strings of the second root array:
+
+ - ``0x0000000000000000000000000000000000000000000000000000000000000003`` (number of characters in word ``"one"``)
+ - ``0x6f6e650000000000000000000000000000000000000000000000000000000000`` (utf8 representation of word ``"one"``)
+ - ``0x0000000000000000000000000000000000000000000000000000000000000003`` (number of characters in word ``"two"``)
+ - ``0x74776f0000000000000000000000000000000000000000000000000000000000`` (utf8 representation of word ``"two"``)
+ - ``0x0000000000000000000000000000000000000000000000000000000000000005`` (number of characters in word ``"three"``)
+ - ``0x7468726565000000000000000000000000000000000000000000000000000000`` (utf8 representation of word ``"three"``)
+
+In parallel to the first root array, since strings are dynamic elements we need to find their offsets ``c``, ``d`` and ``e``:
+
+::
+
+ 0 - c - offset for "one"
+ 1 - d - offset for "two"
+ 2 - e - offset for "three"
+ 3 - 0000000000000000000000000000000000000000000000000000000000000003 - count for "one"
+ 4 - 6f6e650000000000000000000000000000000000000000000000000000000000 - encoding of "one"
+ 5 - 0000000000000000000000000000000000000000000000000000000000000003 - count for "two"
+ 6 - 74776f0000000000000000000000000000000000000000000000000000000000 - encoding of "two"
+ 7 - 0000000000000000000000000000000000000000000000000000000000000005 - count for "three"
+ 8 - 7468726565000000000000000000000000000000000000000000000000000000 - encoding of "three"
+
+Offset ``c`` points to the start of the content of the string ``"one"`` which is line 3 (96 bytes); thus ``c = 0x0000000000000000000000000000000000000000000000000000000000000060``.
+
+Offset ``d`` points to the start of the content of the string ``"two"`` which is line 5 (160 bytes); thus ``d = 0x00000000000000000000000000000000000000000000000000000000000000a0``.
+
+Offset ``e`` points to the start of the content of the string ``"three"`` which is line 7 (224 bytes); thus ``e = 0x00000000000000000000000000000000000000000000000000000000000000e0``.
+
+
+Note that the encodings of the embeded elements of the root arrays are not dependent on each other and have the same encodings for a fuction with a signature ``g(string[],uint[][])``.
+
+Then we encode the length of the first root array:
+
+ - ``0x0000000000000000000000000000000000000000000000000000000000000002`` (number of elements in the first root array, 2; the elements themselves are ``[1, 2]`` and ``[3]``)
+
+Then we encode the length of the second root array:
+
+ - ``0x0000000000000000000000000000000000000000000000000000000000000003`` (number of strings in the second root array, 3; the strings themselves are ``"one"``, ``"two"`` and ``"three"``)
+
+Finally we find the offsets ``f`` and ``g`` for their respective root dynamic arrays ``[[1, 2], [3]]`` and ``["one", "two", "three"]``, and assemble parts in the correct order:
+
+::
+
+ 0x2289b18c - function signature
+ 0 - f - offset of [[1, 2], [3]]
+ 1 - g - offset of ["one", "two", "three"]
+ 2 - 0000000000000000000000000000000000000000000000000000000000000002 - count for [[1, 2], [3]]
+ 3 - 0000000000000000000000000000000000000000000000000000000000000040 - offset of [1, 2]
+ 4 - 00000000000000000000000000000000000000000000000000000000000000a0 - offset of [3]
+ 5 - 0000000000000000000000000000000000000000000000000000000000000002 - count for [1, 2]
+ 6 - 0000000000000000000000000000000000000000000000000000000000000001 - encoding of 1
+ 7 - 0000000000000000000000000000000000000000000000000000000000000002 - encoding of 2
+ 8 - 0000000000000000000000000000000000000000000000000000000000000001 - count for [3]
+ 9 - 0000000000000000000000000000000000000000000000000000000000000003 - encoding of 3
+ 10 - 0000000000000000000000000000000000000000000000000000000000000003 - count for ["one", "two", "three"]
+ 11 - 0000000000000000000000000000000000000000000000000000000000000060 - offset for "one"
+ 12 - 00000000000000000000000000000000000000000000000000000000000000a0 - offset for "two"
+ 13 - 00000000000000000000000000000000000000000000000000000000000000e0 - offset for "three"
+ 14 - 0000000000000000000000000000000000000000000000000000000000000003 - count for "one"
+ 15 - 6f6e650000000000000000000000000000000000000000000000000000000000 - encoding of "one"
+ 16 - 0000000000000000000000000000000000000000000000000000000000000003 - count for "two"
+ 17 - 74776f0000000000000000000000000000000000000000000000000000000000 - encoding of "two"
+ 18 - 0000000000000000000000000000000000000000000000000000000000000005 - count for "three"
+ 19 - 7468726565000000000000000000000000000000000000000000000000000000 - encoding of "three"
+
+Offset ``f`` points to the start of the content of the array ``[[1, 2], [3]]`` which is line 2 (64 bytes); thus ``f = 0x0000000000000000000000000000000000000000000000000000000000000040``.
+
+Offset ``g`` points to the start of the content of the array ``["one", "two", "three"]`` which is line 10 (320 bytes); thus ``g = 0x0000000000000000000000000000000000000000000000000000000000000140``.
+
Events
======
diff --git a/docs/contracts.rst b/docs/contracts.rst
index 4dd185aa..5e7eab80 100644
--- a/docs/contracts.rst
+++ b/docs/contracts.rst
@@ -1323,6 +1323,7 @@ custom types without the overhead of external function calls:
if (carry > 0) {
// too bad, we have to add a limb
uint[] memory newLimbs = new uint[](r.limbs.length + 1);
+ uint i;
for (i = 0; i < r.limbs.length; ++i)
newLimbs[i] = r.limbs[i];
newLimbs[i] = carry;
diff --git a/docs/control-structures.rst b/docs/control-structures.rst
index 7849d15a..cc1f7ca5 100644
--- a/docs/control-structures.rst
+++ b/docs/control-structures.rst
@@ -325,74 +325,7 @@ is ``false``. The default value for the ``uint`` or ``int`` types is ``0``. For
element will be initialized to the default value corresponding to its type. Finally, for dynamically-sized arrays, ``bytes``
and ``string``, the default value is an empty array or string.
-A variable declared anywhere within a function will be in scope for the *entire function*, regardless of where it is declared
-(this will change soon, see below).
-This happens because Solidity inherits its scoping rules from JavaScript.
-This is in contrast to many languages where variables are only scoped where they are declared until the end of the semantic block.
-As a result, the following code is illegal and cause the compiler to throw an error, ``Identifier already declared``:
-
-::
-
- // This will not compile
-
- pragma solidity ^0.4.16;
-
- contract ScopingErrors {
- function scoping() public {
- uint i = 0;
-
- while (i++ < 1) {
- uint same1 = 0;
- }
-
- while (i++ < 2) {
- uint same1 = 0;// Illegal, second declaration of same1
- }
- }
-
- function minimalScoping() public {
- {
- uint same2 = 0;
- }
-
- {
- uint same2 = 0;// Illegal, second declaration of same2
- }
- }
-
- function forLoopScoping() public {
- for (uint same3 = 0; same3 < 1; same3++) {
- }
-
- for (uint same3 = 0; same3 < 1; same3++) {// Illegal, second declaration of same3
- }
- }
- }
-
-In addition to this, if a variable is declared, it will be initialized at the beginning of the function to its default value.
-As a result, the following code is legal, despite being poorly written:
-
-::
-
- pragma solidity ^0.4.0;
-
- contract C {
- function foo() public pure returns (uint) {
- // baz is implicitly initialized as 0
- uint bar = 5;
- if (true) {
- bar += baz;
- } else {
- uint baz = 10;// never executes
- }
- return bar;// returns 5
- }
- }
-
-Scoping starting from Version 0.5.0
------------------------------------
-
-Starting from version 0.5.0, Solidity will change to the more widespread scoping rules of C99
+Scoping in Solidity follows the widespread scoping rules of C99
(and many other languages): Variables are visible from the point right after their declaration
until the end of a ``{ }``-block. As an exception to this rule, variables declared in the
initialization part of a for-loop are only visible until the end of the for-loop.
@@ -401,17 +334,12 @@ Variables and other items declared outside of a code block, for example function
user-defined types, etc., do not change their scoping behaviour. This means you can
use state variables before they are declared and call functions recursively.
-These rules are already introduced now as an experimental feature.
-
As a consequence, the following examples will compile without warnings, since
-the two variables have the same name but disjoint scopes. In non-0.5.0-mode,
-they have the same scope (the function ``minimalScoping``) and thus it does
-not compile there.
+the two variables have the same name but disjoint scopes.
::
- pragma solidity ^0.4.0;
- pragma experimental "v0.5.0";
+ pragma solidity >0.4.24;
contract C {
function minimalScoping() pure public {
{
@@ -430,8 +358,7 @@ In any case, you will get a warning about the outer variable being shadowed.
::
- pragma solidity ^0.4.0;
- pragma experimental "v0.5.0";
+ pragma solidity >0.4.24;
contract C {
function f() pure public returns (uint) {
uint x = 1;
@@ -443,6 +370,24 @@ In any case, you will get a warning about the outer variable being shadowed.
}
}
+.. warning::
+ Before version 0.5.0 Solidity followed the same scoping rules as JavaScript, that is, a variable declared anywhere within a function would be in scope
+ for the entire function, regardless where it was declared. Note that this is a breaking change. The following example shows a code snippet that used
+ to compile but leads to an error starting from version 0.5.0.
+
+ ::
+
+ // This will not compile
+
+ pragma solidity >0.4.24;
+ contract C {
+ function f() pure public returns (uint) {
+ x = 2;
+ uint x;
+ return x;
+ }
+ }
+
.. index:: ! exception, ! throw, ! assert, ! require, ! revert
Error handling: Assert, Require, Revert and Exceptions
diff --git a/libsolidity/analysis/DeclarationContainer.h b/libsolidity/analysis/DeclarationContainer.h
index e4b3320a..a3e0bd0a 100644
--- a/libsolidity/analysis/DeclarationContainer.h
+++ b/libsolidity/analysis/DeclarationContainer.h
@@ -58,7 +58,7 @@ public:
/// @returns whether declaration is valid, and if not also returns previous declaration.
Declaration const* conflictingDeclaration(Declaration const& _declaration, ASTString const* _name = nullptr) const;
- /// Activates a previously inactive (invisible) variable. To be used in C99 scpoing for
+ /// Activates a previously inactive (invisible) variable. To be used in C99 scoping for
/// VariableDeclarationStatements.
void activateVariable(ASTString const& _name);
diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp
index 0a356f04..b856544a 100644
--- a/libsolidity/analysis/NameAndTypeResolver.cpp
+++ b/libsolidity/analysis/NameAndTypeResolver.cpp
@@ -54,11 +54,10 @@ NameAndTypeResolver::NameAndTypeResolver(
bool NameAndTypeResolver::registerDeclarations(SourceUnit& _sourceUnit, ASTNode const* _currentScope)
{
- bool useC99Scoping = _sourceUnit.annotation().experimentalFeatures.count(ExperimentalFeature::V050);
// The helper registers all declarations in m_scopes as a side-effect of its construction.
try
{
- DeclarationRegistrationHelper registrar(m_scopes, _sourceUnit, useC99Scoping, m_errorReporter, _currentScope);
+ DeclarationRegistrationHelper registrar(m_scopes, _sourceUnit, m_errorReporter, _currentScope);
}
catch (FatalError const&)
{
@@ -449,11 +448,9 @@ string NameAndTypeResolver::similarNameSuggestions(ASTString const& _name) const
DeclarationRegistrationHelper::DeclarationRegistrationHelper(
map<ASTNode const*, shared_ptr<DeclarationContainer>>& _scopes,
ASTNode& _astRoot,
- bool _useC99Scoping,
ErrorReporter& _errorReporter,
ASTNode const* _currentScope
):
- m_useC99Scoping(_useC99Scoping),
m_scopes(_scopes),
m_currentScope(_currentScope),
m_errorReporter(_errorReporter)
@@ -629,29 +626,25 @@ void DeclarationRegistrationHelper::endVisit(ModifierDefinition&)
bool DeclarationRegistrationHelper::visit(Block& _block)
{
_block.setScope(m_currentScope);
- if (m_useC99Scoping)
- enterNewSubScope(_block);
+ enterNewSubScope(_block);
return true;
}
void DeclarationRegistrationHelper::endVisit(Block&)
{
- if (m_useC99Scoping)
- closeCurrentScope();
+ closeCurrentScope();
}
bool DeclarationRegistrationHelper::visit(ForStatement& _for)
{
_for.setScope(m_currentScope);
- if (m_useC99Scoping)
- enterNewSubScope(_for);
+ enterNewSubScope(_for);
return true;
}
void DeclarationRegistrationHelper::endVisit(ForStatement&)
{
- if (m_useC99Scoping)
- closeCurrentScope();
+ closeCurrentScope();
}
void DeclarationRegistrationHelper::endVisit(VariableDeclarationStatement& _variableDeclarationStatement)
@@ -716,9 +709,8 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio
if (fun->isConstructor())
warnAboutShadowing = false;
- // Register declaration as inactive if we are in block scope and C99 mode.
+ // Register declaration as inactive if we are in block scope.
bool inactive =
- m_useC99Scoping &&
(dynamic_cast<Block const*>(m_currentScope) || dynamic_cast<ForStatement const*>(m_currentScope));
registerDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, warnAboutShadowing, inactive, m_errorReporter);
diff --git a/libsolidity/analysis/NameAndTypeResolver.h b/libsolidity/analysis/NameAndTypeResolver.h
index 3d10fbd8..8178ee17 100644
--- a/libsolidity/analysis/NameAndTypeResolver.h
+++ b/libsolidity/analysis/NameAndTypeResolver.h
@@ -69,7 +69,7 @@ public:
/// that create their own scope.
/// @returns false in case of error.
bool updateDeclaration(Declaration const& _declaration);
- /// Activates a previously inactive (invisible) variable. To be used in C99 scpoing for
+ /// Activates a previously inactive (invisible) variable. To be used in C99 scoping for
/// VariableDeclarationStatements.
void activateVariable(std::string const& _name);
@@ -142,7 +142,6 @@ public:
DeclarationRegistrationHelper(
std::map<ASTNode const*, std::shared_ptr<DeclarationContainer>>& _scopes,
ASTNode& _astRoot,
- bool _useC99Scoping,
ErrorReporter& _errorReporter,
ASTNode const* _currentScope = nullptr
);
@@ -190,7 +189,6 @@ private:
/// @returns the canonical name of the current scope.
std::string currentCanonicalName() const;
- bool m_useC99Scoping = false;
std::map<ASTNode const*, std::shared_ptr<DeclarationContainer>>& m_scopes;
ASTNode const* m_currentScope = nullptr;
VariableScope* m_currentFunction = nullptr;
diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp
index a051d7f9..58b659f7 100644
--- a/libsolidity/analysis/ReferencesResolver.cpp
+++ b/libsolidity/analysis/ReferencesResolver.cpp
@@ -48,9 +48,7 @@ bool ReferencesResolver::visit(Block const& _block)
if (!m_resolveInsideCode)
return false;
m_experimental050Mode = _block.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
- // C99-scoped variables
- if (m_experimental050Mode)
- m_resolver.setScope(&_block);
+ m_resolver.setScope(&_block);
return true;
}
@@ -59,9 +57,7 @@ void ReferencesResolver::endVisit(Block const& _block)
if (!m_resolveInsideCode)
return;
- // C99-scoped variables
- if (m_experimental050Mode)
- m_resolver.setScope(_block.scope());
+ m_resolver.setScope(_block.scope());
}
bool ReferencesResolver::visit(ForStatement const& _for)
@@ -69,9 +65,7 @@ bool ReferencesResolver::visit(ForStatement const& _for)
if (!m_resolveInsideCode)
return false;
m_experimental050Mode = _for.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
- // C99-scoped variables
- if (m_experimental050Mode)
- m_resolver.setScope(&_for);
+ m_resolver.setScope(&_for);
return true;
}
@@ -79,18 +73,16 @@ void ReferencesResolver::endVisit(ForStatement const& _for)
{
if (!m_resolveInsideCode)
return;
- if (m_experimental050Mode)
- m_resolver.setScope(_for.scope());
+ m_resolver.setScope(_for.scope());
}
void ReferencesResolver::endVisit(VariableDeclarationStatement const& _varDeclStatement)
{
if (!m_resolveInsideCode)
return;
- if (m_experimental050Mode)
- for (auto const& var: _varDeclStatement.declarations())
- if (var)
- m_resolver.activateVariable(var->name());
+ for (auto const& var: _varDeclStatement.declarations())
+ if (var)
+ m_resolver.activateVariable(var->name());
}
bool ReferencesResolver::visit(Identifier const& _identifier)
@@ -99,9 +91,14 @@ bool ReferencesResolver::visit(Identifier const& _identifier)
if (declarations.empty())
{
string suggestions = m_resolver.similarNameSuggestions(_identifier.name());
- string errorMessage =
- "Undeclared identifier." +
- (suggestions.empty()? "": " Did you mean " + std::move(suggestions) + "?");
+ string errorMessage = "Undeclared identifier.";
+ if (!suggestions.empty())
+ {
+ if ("\"" + _identifier.name() + "\"" == suggestions)
+ errorMessage += " " + std::move(suggestions) + " is not (or not yet) visible at this point.";
+ else
+ errorMessage += " Did you mean " + std::move(suggestions) + "?";
+ }
declarationError(_identifier.location(), errorMessage);
}
else if (declarations.size() == 1)
diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp
index f234dcaf..c408b393 100644
--- a/libsolidity/analysis/SyntaxChecker.cpp
+++ b/libsolidity/analysis/SyntaxChecker.cpp
@@ -255,7 +255,7 @@ bool SyntaxChecker::visit(FunctionTypeName const& _node)
for (auto const& decl: _node.returnParameterTypeList()->parameters())
if (!decl->name().empty())
- m_errorReporter.warning(decl->location(), "Naming function type return parameters is deprecated.");
+ m_errorReporter.syntaxError(decl->location(), "Return parameters in function types may not be named.");
return true;
}
diff --git a/test/compilationTests/corion/provider.sol b/test/compilationTests/corion/provider.sol
index 5fa90fcd..dba1253d 100644
--- a/test/compilationTests/corion/provider.sol
+++ b/test/compilationTests/corion/provider.sol
@@ -536,8 +536,9 @@ contract provider is module, safeMath, announcementTypes {
address provAddr;
uint256 provHeight;
bool interest = false;
+ uint256 a;
var rate = clients[msg.sender].lastRate;
- for ( uint256 a = (clients[msg.sender].paidUpTo + 1) ; a <= currentSchellingRound ; a++ ) {
+ for ( a = (clients[msg.sender].paidUpTo + 1) ; a <= currentSchellingRound ; a++ ) {
if (globalFunds[a].reward > 0 && globalFunds[a].supply > 0) {
provAddr = clients[msg.sender].providerAddress;
provHeight = clients[msg.sender].providerHeight;
@@ -585,8 +586,9 @@ contract provider is module, safeMath, announcementTypes {
uint256 steps;
uint256 currHeight = providers[addr].currentHeight;
uint256 LTSID = providers[addr].data[currHeight].lastSupplyID;
+ uint256 a;
var rate = providers[addr].data[currHeight].lastPaidRate;
- for ( uint256 a = (providers[addr].data[currHeight].paidUpTo + 1) ; a <= currentSchellingRound ; a++ ) {
+ for ( a = (providers[addr].data[currHeight].paidUpTo + 1) ; a <= currentSchellingRound ; a++ ) {
if (globalFunds[a].reward > 0 && globalFunds[a].supply > 0) {
if ( providers[addr].data[currHeight].rateHistory[a].valid ) {
rate = providers[addr].data[currHeight].rateHistory[a].value;
diff --git a/test/compilationTests/stringutils/strings.sol b/test/compilationTests/stringutils/strings.sol
index 771f7a53..939a777a 100644
--- a/test/compilationTests/stringutils/strings.sol
+++ b/test/compilationTests/stringutils/strings.sol
@@ -155,7 +155,8 @@ library strings {
// Starting at ptr-31 means the LSB will be the byte we care about
var ptr = self._ptr - 31;
var end = ptr + self._len;
- for (uint len = 0; ptr < end; len++) {
+ uint len;
+ for (len = 0; ptr < end; len++) {
uint8 b;
assembly { b := and(mload(ptr), 0xFF) }
if (b < 0x80) {
@@ -695,7 +696,7 @@ library strings {
uint retptr;
assembly { retptr := add(ret, 32) }
- for(i = 0; i < parts.length; i++) {
+ for(uint i = 0; i < parts.length; i++) {
memcpy(retptr, parts[i]._ptr, parts[i]._len);
retptr += parts[i]._len;
if (i < parts.length - 1) {
diff --git a/test/libsolidity/SMTChecker.cpp b/test/libsolidity/SMTChecker.cpp
index ec23f452..18c8c025 100644
--- a/test/libsolidity/SMTChecker.cpp
+++ b/test/libsolidity/SMTChecker.cpp
@@ -133,22 +133,6 @@ BOOST_AUTO_TEST_CASE(assignment_in_declaration)
CHECK_SUCCESS_NO_WARNINGS(text);
}
-BOOST_AUTO_TEST_CASE(use_before_declaration)
-{
- string text = R"(
- contract C {
- function f() public pure { a = 3; uint a = 2; assert(a == 2); }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- text = R"(
- contract C {
- function f() public pure { assert(a == 0); uint a = 2; assert(a == 2); }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
BOOST_AUTO_TEST_CASE(function_call_does_not_clear_local_vars)
{
string text = R"(
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 2a24a1e3..65473f0d 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -5011,7 +5011,7 @@ BOOST_AUTO_TEST_CASE(byte_array_push_transition)
if (data.length != i) return 0x1000 + i;
if (data[data.length - 1] != byte(i)) return i;
}
- for (i = 1; i < 40; i++)
+ for (uint8 i = 1; i < 40; i++)
if (data[i - 1] != byte(i)) return 0x1000000 + i;
return 0;
}
diff --git a/test/libsolidity/syntaxTests/double_variable_declaration.sol b/test/libsolidity/syntaxTests/double_variable_declaration.sol
index 9ab87959..53c5c9be 100644
--- a/test/libsolidity/syntaxTests/double_variable_declaration.sol
+++ b/test/libsolidity/syntaxTests/double_variable_declaration.sol
@@ -1,8 +1,9 @@
contract test {
function f() pure public {
uint256 x;
- if (true) { uint256 x; }
+ x = 1;
+ if (true) { uint256 x; x = 2; }
}
}
// ----
-// DeclarationError: (71-80): Identifier already declared.
+// Warning: (80-89): This declaration shadows an existing declaration.
diff --git a/test/libsolidity/syntaxTests/double_variable_declaration_050.sol b/test/libsolidity/syntaxTests/double_variable_declaration_050.sol
deleted file mode 100644
index 2f47e6dc..00000000
--- a/test/libsolidity/syntaxTests/double_variable_declaration_050.sol
+++ /dev/null
@@ -1,11 +0,0 @@
-pragma experimental "v0.5.0";
-contract test {
- function f() pure public {
- uint256 x;
- if (true) { uint256 x; }
- }
-}
-// ----
-// Warning: (101-110): This declaration shadows an existing declaration.
-// Warning: (76-85): Unused local variable.
-// Warning: (101-110): Unused local variable.
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_return_parameters_with_names.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_return_parameters_with_names.sol
new file mode 100644
index 00000000..12191530
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_return_parameters_with_names.sol
@@ -0,0 +1,5 @@
+contract C {
+ function(uint) returns (bool ret) f;
+}
+// ----
+// SyntaxError: (41-49): Return parameters in function types may not be named.
diff --git a/test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol b/test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol
deleted file mode 100644
index 67a74e54..00000000
--- a/test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol
+++ /dev/null
@@ -1,5 +0,0 @@
-contract C {
- function(uint) returns (bool ret) f;
-}
-// ----
-// Warning: (41-49): Naming function type return parameters is deprecated.
diff --git a/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol
index 00031924..76bb6fc0 100644
--- a/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol
+++ b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol
@@ -2,3 +2,5 @@ contract B {
function f() mod(x) pure public { uint x = 7; }
modifier mod(uint a) { if (a > 0) _; }
}
+// ----
+// DeclarationError: (34-35): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables050.sol b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables050.sol
deleted file mode 100644
index c19ccf2c..00000000
--- a/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables050.sol
+++ /dev/null
@@ -1,7 +0,0 @@
-pragma experimental "v0.5.0";
-contract B {
- function f() mod(x) pure public { uint x = 7; }
- modifier mod(uint a) { if (a > 0) _; }
-}
-// ----
-// DeclarationError: (64-65): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationScoping.sol b/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationScoping.sol
index 3ba85f69..224d9614 100644
--- a/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationScoping.sol
+++ b/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationScoping.sol
@@ -1,5 +1,3 @@
-pragma experimental "v0.5.0";
-
contract C {
function f() internal {
{
@@ -9,4 +7,4 @@ contract C {
}
}
// ----
-// DeclarationError: (130-131): Undeclared identifier.
+// DeclarationError: (99-100): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationScoping2.sol b/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationScoping2.sol
index e21181de..242a1f39 100644
--- a/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationScoping2.sol
+++ b/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationScoping2.sol
@@ -1,5 +1,3 @@
-pragma experimental "v0.5.0";
-
contract C {
function f() internal {
{
@@ -8,6 +6,6 @@ contract C {
}
}
// ----
-// DeclarationError: (110-111): Undeclared identifier. Did you mean "a"?
-// DeclarationError: (113-114): Undeclared identifier. Did you mean "b"?
-// DeclarationError: (116-117): Undeclared identifier. Did you mean "c"?
+// DeclarationError: (79-80): Undeclared identifier. "a" is not (or not yet) visible at this point.
+// DeclarationError: (82-83): Undeclared identifier. "b" is not (or not yet) visible at this point.
+// DeclarationError: (85-86): Undeclared identifier. "c" is not (or not yet) visible at this point.
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/137_external_visibility.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/137_external_visibility.sol
index 2a0cbde0..214ad60a 100644
--- a/test/libsolidity/syntaxTests/nameAndTypeResolution/137_external_visibility.sol
+++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/137_external_visibility.sol
@@ -3,4 +3,4 @@ contract c {
function g() public { f(); }
}
// ----
-// DeclarationError: (68-69): Undeclared identifier. Did you mean "f"?
+// DeclarationError: (68-69): Undeclared identifier. "f" is not (or not yet) visible at this point.
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/448_no_unused_dec_after_use.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/448_no_unused_dec_after_use.sol
deleted file mode 100644
index 3bfa9cb8..00000000
--- a/test/libsolidity/syntaxTests/nameAndTypeResolution/448_no_unused_dec_after_use.sol
+++ /dev/null
@@ -1,6 +0,0 @@
-contract C {
- function f() pure public {
- a = 7;
- uint a;
- }
-}
diff --git a/test/libsolidity/syntaxTests/parsing/conditional_with_assignment.sol b/test/libsolidity/syntaxTests/parsing/conditional_with_assignment.sol
index 6f8040d6..7489aaf9 100644
--- a/test/libsolidity/syntaxTests/parsing/conditional_with_assignment.sol
+++ b/test/libsolidity/syntaxTests/parsing/conditional_with_assignment.sol
@@ -1,11 +1,8 @@
contract A {
- function f() {
+ function f() public pure {
uint y = 1;
- uint x = 3 < 0 ? x = 3 : 6;
+ uint x = 3 < 0 ? y = 3 : 6;
true ? x = 3 : 4;
}
}
// ----
-// Warning: (17-119): No visibility specified. Defaulting to "public".
-// Warning: (40-46): Unused local variable.
-// Warning: (17-119): Function state mutability can be restricted to pure
diff --git a/test/libsolidity/syntaxTests/parsing/function_type_in_struct.sol b/test/libsolidity/syntaxTests/parsing/function_type_in_struct.sol
index d3c84678..c7703b47 100644
--- a/test/libsolidity/syntaxTests/parsing/function_type_in_struct.sol
+++ b/test/libsolidity/syntaxTests/parsing/function_type_in_struct.sol
@@ -1,6 +1,6 @@
contract test {
struct S {
- function (uint x, uint y) internal returns (uint a) f;
+ function (uint x, uint y) internal returns (uint) f;
function (uint, uint) external returns (uint) g;
uint d;
}
@@ -8,4 +8,3 @@ contract test {
// ----
// Warning: (49-55): Naming function type parameters is deprecated.
// Warning: (57-63): Naming function type parameters is deprecated.
-// Warning: (83-89): Naming function type return parameters is deprecated.
diff --git a/test/libsolidity/syntaxTests/parsing/while_loop.sol b/test/libsolidity/syntaxTests/parsing/while_loop.sol
index 129b52e1..dbb00a69 100644
--- a/test/libsolidity/syntaxTests/parsing/while_loop.sol
+++ b/test/libsolidity/syntaxTests/parsing/while_loop.sol
@@ -1,9 +1,7 @@
contract test {
- function fun(uint256 a) {
- while (true) { uint256 x = 1; break; continue; } x = 9;
+ function fun() public pure {
+ uint256 x;
+ while (true) { x = 1; break; continue; } x = 9;
}
}
// ----
-// Warning: (20-115): No visibility specified. Defaulting to "public".
-// Warning: (33-42): Unused function parameter. Remove or comment out the variable name to silence this warning.
-// Warning: (20-115): Function state mutability can be restricted to pure
diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope.sol
index d90ec2d7..36bae6a8 100644
--- a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope.sol
+++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope.sol
@@ -5,4 +5,5 @@ contract test {
}
}
// ----
-// DeclarationError: (77-83): Identifier already declared.
+// Warning: (57-63): Unused local variable.
+// Warning: (77-83): Unused local variable.
diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_050.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_050.sol
deleted file mode 100644
index 06bfe7be..00000000
--- a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_050.sol
+++ /dev/null
@@ -1,10 +0,0 @@
-pragma experimental "v0.5.0";
-contract test {
- function f() pure public {
- { uint x; }
- { uint x; }
- }
-}
-// ----
-// Warning: (87-93): Unused local variable.
-// Warning: (107-113): Unused local variable.
diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation.sol
index 1a5ff2f9..0c03ec3e 100644
--- a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation.sol
+++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation.sol
@@ -5,4 +5,5 @@ contract test {
}
}
// ----
-// DeclarationError: (75-81): Identifier already declared.
+// Warning: (57-63): Unused local variable.
+// Warning: (75-81): Unused local variable.
diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation_050.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation_050.sol
deleted file mode 100644
index 20ea0349..00000000
--- a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation_050.sol
+++ /dev/null
@@ -1,10 +0,0 @@
-pragma experimental "v0.5.0";
-contract test {
- function f() pure public {
- { uint x; }
- uint x;
- }
-}
-// ----
-// Warning: (87-93): Unused local variable.
-// Warning: (105-111): Unused local variable.
diff --git a/test/libsolidity/syntaxTests/scoping/scoping.sol b/test/libsolidity/syntaxTests/scoping/scoping.sol
index 34b055d9..dae5a42d 100644
--- a/test/libsolidity/syntaxTests/scoping/scoping.sol
+++ b/test/libsolidity/syntaxTests/scoping/scoping.sol
@@ -1,4 +1,3 @@
-pragma experimental "v0.5.0";
contract test {
function f() public {
{
@@ -8,4 +7,4 @@ contract test {
}
}
// ----
-// DeclarationError: (123-124): Undeclared identifier.
+// DeclarationError: (93-94): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_activation.sol b/test/libsolidity/syntaxTests/scoping/scoping_activation.sol
index 7334bc49..8522a0e3 100644
--- a/test/libsolidity/syntaxTests/scoping/scoping_activation.sol
+++ b/test/libsolidity/syntaxTests/scoping/scoping_activation.sol
@@ -1,4 +1,3 @@
-pragma experimental "v0.5.0";
contract test {
function f() pure public {
x = 3;
@@ -6,4 +5,4 @@ contract test {
}
}
// ----
-// DeclarationError: (85-86): Undeclared identifier. Did you mean "x"?
+// DeclarationError: (55-56): Undeclared identifier. "x" is not (or not yet) visible at this point.
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_activation_old.sol b/test/libsolidity/syntaxTests/scoping/scoping_activation_old.sol
index d893a889..8522a0e3 100644
--- a/test/libsolidity/syntaxTests/scoping/scoping_activation_old.sol
+++ b/test/libsolidity/syntaxTests/scoping/scoping_activation_old.sol
@@ -4,3 +4,5 @@ contract test {
uint x;
}
}
+// ----
+// DeclarationError: (55-56): Undeclared identifier. "x" is not (or not yet) visible at this point.
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_for.sol b/test/libsolidity/syntaxTests/scoping/scoping_for.sol
index 6e5b7095..a882d1ca 100644
--- a/test/libsolidity/syntaxTests/scoping/scoping_for.sol
+++ b/test/libsolidity/syntaxTests/scoping/scoping_for.sol
@@ -1,4 +1,3 @@
-pragma experimental "v0.5.0";
contract test {
function f() pure public {
for (uint x = 0; x < 10; x ++){
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_for2.sol b/test/libsolidity/syntaxTests/scoping/scoping_for2.sol
index eb74b8ab..f8c5c19b 100644
--- a/test/libsolidity/syntaxTests/scoping/scoping_for2.sol
+++ b/test/libsolidity/syntaxTests/scoping/scoping_for2.sol
@@ -1,4 +1,3 @@
-pragma experimental "v0.5.0";
contract test {
function f() pure public {
for (uint x = 0; x < 10; x ++)
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_for3.sol b/test/libsolidity/syntaxTests/scoping/scoping_for3.sol
index 1814cb47..81e34562 100644
--- a/test/libsolidity/syntaxTests/scoping/scoping_for3.sol
+++ b/test/libsolidity/syntaxTests/scoping/scoping_for3.sol
@@ -1,4 +1,3 @@
-pragma experimental "v0.5.0";
contract test {
function f() pure public {
for (uint x = 0; x < 10; x ++){
@@ -8,4 +7,4 @@ contract test {
}
}
// ----
-// DeclarationError: (154-155): Undeclared identifier.
+// DeclarationError: (124-125): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_for_decl_in_body.sol b/test/libsolidity/syntaxTests/scoping/scoping_for_decl_in_body.sol
index 3e80b385..28b88525 100644
--- a/test/libsolidity/syntaxTests/scoping/scoping_for_decl_in_body.sol
+++ b/test/libsolidity/syntaxTests/scoping/scoping_for_decl_in_body.sol
@@ -1,4 +1,3 @@
-pragma experimental "v0.5.0";
contract test {
function f() pure public {
for (;; y++){
@@ -7,4 +6,4 @@ contract test {
}
}
// ----
-// DeclarationError: (93-94): Undeclared identifier.
+// DeclarationError: (63-64): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_old.sol b/test/libsolidity/syntaxTests/scoping/scoping_old.sol
index 83f6b60b..70e5ee0c 100644
--- a/test/libsolidity/syntaxTests/scoping/scoping_old.sol
+++ b/test/libsolidity/syntaxTests/scoping/scoping_old.sol
@@ -4,3 +4,5 @@ contract test {
uint256 x = 2;
}
}
+// ----
+// DeclarationError: (55-56): Undeclared identifier. "x" is not (or not yet) visible at this point.
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_self_use.sol b/test/libsolidity/syntaxTests/scoping/scoping_self_use.sol
index 9e2c0171..a5087c57 100644
--- a/test/libsolidity/syntaxTests/scoping/scoping_self_use.sol
+++ b/test/libsolidity/syntaxTests/scoping/scoping_self_use.sol
@@ -3,3 +3,5 @@ contract test {
uint a = a;
}
}
+// ----
+// DeclarationError: (64-65): Undeclared identifier. "a" is not (or not yet) visible at this point.
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_self_use_050.sol b/test/libsolidity/syntaxTests/scoping/scoping_self_use_050.sol
deleted file mode 100644
index ab3dcefb..00000000
--- a/test/libsolidity/syntaxTests/scoping/scoping_self_use_050.sol
+++ /dev/null
@@ -1,8 +0,0 @@
-pragma experimental "v0.5.0";
-contract test {
- function f() pure public {
- uint a = a;
- }
-}
-// ----
-// DeclarationError: (94-95): Undeclared identifier. Did you mean "a"?