mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #10255 from ethereum/this-super-underscore-reserved-identifiers
[BREAKING] Disallow declarations with name "this", "super" and "_"
This commit is contained in:
commit
38f143c597
@ -13,6 +13,7 @@ Breaking Changes:
|
||||
* Code Generator: Use ``revert`` with error signature ``Panic(uint256)`` and error codes instead of invalid opcode on failing assertions.
|
||||
* Type System: Explicit conversions from literals to integer type is as strict as implicit conversions.
|
||||
* Type System: Explicit conversions from literals to enums are only allowed if the value fits in the enum.
|
||||
* Type System: Declarations with the name ``this``, ``super`` and ``_`` are disallowed, with the exception of public functions and events.
|
||||
|
||||
Language Features:
|
||||
* Super constructors can now be called using the member notation e.g. ``M.C(123)``.
|
||||
|
@ -58,3 +58,6 @@ New Restrictions
|
||||
* ``enum`` definitions cannot contain more than 256 members.
|
||||
|
||||
This will make it safe to assume that the underlying type in the ABI is always ``uint8``.
|
||||
|
||||
* Declarations with the name ``this``, ``super`` and ``_`` are disallowed, with the exception of
|
||||
public functions and events.
|
||||
|
@ -509,6 +509,33 @@ bool DeclarationRegistrationHelper::registerDeclaration(
|
||||
// We use "invisible" for both inactive variables in blocks and for members invisible in contracts.
|
||||
// They cannot both be true at the same time.
|
||||
solAssert(!(_inactive && !_declaration.isVisibleInContract()), "");
|
||||
|
||||
static set<string> illegalNames{"_", "super", "this"};
|
||||
|
||||
if (illegalNames.count(name))
|
||||
{
|
||||
auto isPublicFunctionOrEvent = [](Declaration const* _d) -> bool
|
||||
{
|
||||
if (auto functionDefinition = dynamic_cast<FunctionDefinition const*>(_d))
|
||||
{
|
||||
if (!functionDefinition->isFree() && functionDefinition->isPublic())
|
||||
return true;
|
||||
}
|
||||
else if (dynamic_cast<EventDefinition const*>(_d))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// We allow an exception for public functions or events.
|
||||
if (!isPublicFunctionOrEvent(&_declaration))
|
||||
_errorReporter.declarationError(
|
||||
3726_error,
|
||||
*_errorLocation,
|
||||
"The name \"" + name + "\" is reserved."
|
||||
);
|
||||
}
|
||||
|
||||
if (!_container.registerDeclaration(_declaration, _name, _errorLocation, !_declaration.isVisibleInContract() || _inactive, false))
|
||||
{
|
||||
SourceLocation firstDeclarationLocation;
|
||||
|
@ -380,4 +380,11 @@ void ReferencesResolver::validateYulIdentifierName(yul::YulString _name, SourceL
|
||||
_location,
|
||||
"User-defined identifiers in inline assembly cannot contain '.'."
|
||||
);
|
||||
|
||||
if (set<string>{"this", "super", "_"}.count(_name.str()))
|
||||
m_errorReporter.declarationError(
|
||||
4113_error,
|
||||
_location,
|
||||
"The identifier name \"" + _name.str() + "\" is reserved."
|
||||
);
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
contract C {
|
||||
function f() public pure returns (uint) {
|
||||
uint _;
|
||||
return _;
|
||||
}
|
||||
|
||||
function g() public pure returns (uint) {
|
||||
uint _ = 1;
|
||||
return _;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// compileToEwasm: also
|
||||
// ----
|
||||
// f() -> 0
|
||||
// g() -> 1
|
@ -1,23 +0,0 @@
|
||||
contract C {
|
||||
modifier m() {
|
||||
_;
|
||||
}
|
||||
|
||||
modifier n() {
|
||||
string memory _ = "failed";
|
||||
_;
|
||||
revert(_);
|
||||
}
|
||||
|
||||
function f() m() public returns (uint) {
|
||||
return 88;
|
||||
}
|
||||
|
||||
function g() n() public returns (uint) {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// ----
|
||||
// f() -> 88
|
||||
// g() -> FAILURE, hex"08c379a0", 0x20, 6, "failed"
|
@ -1,24 +0,0 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C
|
||||
{
|
||||
uint public x;
|
||||
C c;
|
||||
function f(C _c) public {
|
||||
c = _c;
|
||||
}
|
||||
function g() public {
|
||||
C this = c;
|
||||
x = 0;
|
||||
this.h();
|
||||
// State knowledge is erased.
|
||||
// Function call is not inlined.
|
||||
assert(x == 0);
|
||||
}
|
||||
function h() public {
|
||||
x = 2;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2319: (160-166): This declaration shadows a builtin symbol.
|
||||
// Warning 6328: (268-282): CHC: Assertion violation happens here.
|
@ -0,0 +1,12 @@
|
||||
// Exception for the rule about illegal names.
|
||||
contract C {
|
||||
function this() public {
|
||||
}
|
||||
function super() public {
|
||||
}
|
||||
function _() public {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2319: (61-88): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (90-118): This declaration shadows a builtin symbol.
|
@ -0,0 +1,17 @@
|
||||
contract C {
|
||||
function _() internal returns(uint) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
function super() internal {
|
||||
}
|
||||
|
||||
function this() internal {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 3726: (17-78): The name "_" is reserved.
|
||||
// DeclarationError 3726: (84-117): The name "super" is reserved.
|
||||
// DeclarationError 3726: (123-155): The name "this" is reserved.
|
||||
// Warning 2319: (84-117): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (123-155): This declaration shadows a builtin symbol.
|
31
test/libsolidity/syntaxTests/enums/illegal_names.sol
Normal file
31
test/libsolidity/syntaxTests/enums/illegal_names.sol
Normal file
@ -0,0 +1,31 @@
|
||||
enum this {
|
||||
a
|
||||
}
|
||||
enum super {
|
||||
b
|
||||
}
|
||||
enum _ {
|
||||
c
|
||||
}
|
||||
|
||||
enum E {
|
||||
this,
|
||||
super,
|
||||
_
|
||||
}
|
||||
|
||||
contract C {
|
||||
this a;
|
||||
super b;
|
||||
_ c;
|
||||
E e;
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 3726: (0-19): The name "this" is reserved.
|
||||
// DeclarationError 3726: (20-40): The name "super" is reserved.
|
||||
// DeclarationError 3726: (41-57): The name "_" is reserved.
|
||||
// DeclarationError 3726: (72-76): The name "this" is reserved.
|
||||
// DeclarationError 3726: (82-87): The name "super" is reserved.
|
||||
// DeclarationError 3726: (93-94): The name "_" is reserved.
|
||||
// Warning 2319: (0-19): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (20-40): This declaration shadows a builtin symbol.
|
@ -0,0 +1,9 @@
|
||||
// Exception for the illegal name list. External interface events
|
||||
contract C {
|
||||
event this();
|
||||
event super();
|
||||
event _();
|
||||
}
|
||||
// ----
|
||||
// Warning 2319: (80-93): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (95-109): This declaration shadows a builtin symbol.
|
17
test/libsolidity/syntaxTests/freeFunctions/illegal_names.sol
Normal file
17
test/libsolidity/syntaxTests/freeFunctions/illegal_names.sol
Normal file
@ -0,0 +1,17 @@
|
||||
function this() {}
|
||||
function super() {}
|
||||
function _() {}
|
||||
|
||||
contract C {
|
||||
function test() public {
|
||||
this();
|
||||
super();
|
||||
_();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 3726: (0-18): The name "this" is reserved.
|
||||
// DeclarationError 3726: (19-38): The name "super" is reserved.
|
||||
// DeclarationError 3726: (39-54): The name "_" is reserved.
|
||||
// Warning 2319: (0-18): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (19-38): This declaration shadows a builtin symbol.
|
11
test/libsolidity/syntaxTests/immutable/illegal_names.sol
Normal file
11
test/libsolidity/syntaxTests/immutable/illegal_names.sol
Normal file
@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
uint immutable super;
|
||||
uint immutable _;
|
||||
uint immutable this;
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 3726: (17-37): The name "super" is reserved.
|
||||
// DeclarationError 3726: (43-59): The name "_" is reserved.
|
||||
// DeclarationError 3726: (65-84): The name "this" is reserved.
|
||||
// Warning 2319: (17-37): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (65-84): This declaration shadows a builtin symbol.
|
@ -0,0 +1,55 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
// reserved function names
|
||||
assembly {
|
||||
function this() {
|
||||
}
|
||||
function super() {
|
||||
}
|
||||
function _() {
|
||||
}
|
||||
}
|
||||
|
||||
// reserved names as function argument
|
||||
assembly {
|
||||
function a(this) {
|
||||
}
|
||||
function b(super) {
|
||||
}
|
||||
function c(_) {
|
||||
}
|
||||
}
|
||||
|
||||
// reserved names as function return parameter
|
||||
assembly {
|
||||
function d() -> this {
|
||||
}
|
||||
function g() -> super {
|
||||
}
|
||||
function c() -> _ {
|
||||
}
|
||||
}
|
||||
|
||||
// reserved names as variable declaration
|
||||
assembly {
|
||||
let this := 1
|
||||
let super := 1
|
||||
let _ := 1
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 4113: (105-136): The identifier name "this" is reserved.
|
||||
// DeclarationError 4113: (149-181): The identifier name "super" is reserved.
|
||||
// DeclarationError 4113: (194-222): The identifier name "_" is reserved.
|
||||
// DeclarationError 4113: (323-327): The identifier name "this" is reserved.
|
||||
// DeclarationError 4113: (368-373): The identifier name "super" is reserved.
|
||||
// DeclarationError 4113: (414-415): The identifier name "_" is reserved.
|
||||
// DeclarationError 4113: (546-550): The identifier name "this" is reserved.
|
||||
// DeclarationError 4113: (595-600): The identifier name "super" is reserved.
|
||||
// DeclarationError 4113: (645-646): The identifier name "_" is reserved.
|
||||
// DeclarationError 4113: (759-763): The identifier name "this" is reserved.
|
||||
// DeclarationError 3859: (759-763): This declaration shadows a declaration outside the inline assembly block.
|
||||
// DeclarationError 4113: (785-790): The identifier name "super" is reserved.
|
||||
// DeclarationError 3859: (785-790): This declaration shadows a declaration outside the inline assembly block.
|
||||
// DeclarationError 4113: (812-813): The identifier name "_" is reserved.
|
11
test/libsolidity/syntaxTests/modifiers/illegal_name.sol
Normal file
11
test/libsolidity/syntaxTests/modifiers/illegal_name.sol
Normal file
@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
modifier this { _; }
|
||||
modifier super { _; }
|
||||
modifier _ { _; }
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 3726: (14-34): The name "this" is reserved.
|
||||
// DeclarationError 3726: (36-57): The name "super" is reserved.
|
||||
// DeclarationError 3726: (59-76): The name "_" is reserved.
|
||||
// Warning 2319: (14-34): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (36-57): This declaration shadows a builtin symbol.
|
@ -0,0 +1,16 @@
|
||||
contract C {
|
||||
function f() public pure {
|
||||
assembly {
|
||||
function this() {
|
||||
}
|
||||
function super() {
|
||||
}
|
||||
function _() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 4113: (75-106): The identifier name "this" is reserved.
|
||||
// DeclarationError 4113: (119-151): The identifier name "super" is reserved.
|
||||
// DeclarationError 4113: (164-192): The identifier name "_" is reserved.
|
@ -0,0 +1,15 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
assembly {
|
||||
let super := 1
|
||||
let this := 1
|
||||
let _ := 1
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 4113: (74-79): The identifier name "super" is reserved.
|
||||
// DeclarationError 3859: (74-79): This declaration shadows a declaration outside the inline assembly block.
|
||||
// DeclarationError 4113: (101-105): The identifier name "this" is reserved.
|
||||
// DeclarationError 3859: (101-105): This declaration shadows a declaration outside the inline assembly block.
|
||||
// DeclarationError 4113: (127-128): The identifier name "_" is reserved.
|
@ -0,0 +1,28 @@
|
||||
contract C {
|
||||
function f(uint super) public {
|
||||
}
|
||||
function g(uint this) public {
|
||||
}
|
||||
function h(uint _) public {
|
||||
}
|
||||
function i() public returns (uint super) {
|
||||
return 1;
|
||||
}
|
||||
function j() public returns (uint this) {
|
||||
return 1;
|
||||
}
|
||||
function k() public returns (uint _) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 3726: (28-38): The name "super" is reserved.
|
||||
// DeclarationError 3726: (70-79): The name "this" is reserved.
|
||||
// DeclarationError 3726: (111-117): The name "_" is reserved.
|
||||
// DeclarationError 3726: (167-177): The name "super" is reserved.
|
||||
// DeclarationError 3726: (238-247): The name "this" is reserved.
|
||||
// DeclarationError 3726: (308-314): The name "_" is reserved.
|
||||
// Warning 2319: (28-38): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (70-79): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (167-177): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (238-247): This declaration shadows a builtin symbol.
|
@ -0,0 +1,26 @@
|
||||
library super {
|
||||
function f() public {
|
||||
}
|
||||
}
|
||||
|
||||
library this {
|
||||
function f() public {
|
||||
}
|
||||
}
|
||||
library _ {
|
||||
function f() public {
|
||||
}
|
||||
}
|
||||
|
||||
contract C {
|
||||
// These are not errors
|
||||
using super for uint;
|
||||
using this for uint16;
|
||||
using _ for int;
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 3726: (0-49): The name "super" is reserved.
|
||||
// DeclarationError 3726: (51-99): The name "this" is reserved.
|
||||
// DeclarationError 3726: (100-145): The name "_" is reserved.
|
||||
// Warning 2319: (0-49): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (51-99): This declaration shadows a builtin symbol.
|
@ -0,0 +1,32 @@
|
||||
library L {
|
||||
function f() public {
|
||||
}
|
||||
}
|
||||
|
||||
// error
|
||||
struct super {
|
||||
uint a;
|
||||
}
|
||||
|
||||
// error
|
||||
struct this {
|
||||
uint a;
|
||||
}
|
||||
|
||||
// error
|
||||
struct _ {
|
||||
uint a;
|
||||
}
|
||||
|
||||
contract C {
|
||||
// These are not errors
|
||||
using L for super;
|
||||
using L for _;
|
||||
using L for this;
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 3726: (56-84): The name "super" is reserved.
|
||||
// DeclarationError 3726: (95-122): The name "this" is reserved.
|
||||
// DeclarationError 3726: (133-157): The name "_" is reserved.
|
||||
// Warning 2319: (56-84): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (95-122): This declaration shadows a builtin symbol.
|
@ -5,7 +5,7 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 3726: (52-62): The name "super" is reserved.
|
||||
// DeclarationError 3726: (76-85): The name "this" is reserved.
|
||||
// Warning 2319: (52-62): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (76-85): This declaration shadows a builtin symbol.
|
||||
// Warning 2072: (52-62): Unused local variable.
|
||||
// Warning 2072: (76-85): Unused local variable.
|
||||
|
@ -5,4 +5,4 @@ contract c {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2018: (17-105): Function state mutability can be restricted to pure
|
||||
// DeclarationError 3726: (66-72): The name "_" is reserved.
|
||||
|
15
test/libsolidity/syntaxTests/structs/illegal_names.sol
Normal file
15
test/libsolidity/syntaxTests/structs/illegal_names.sol
Normal file
@ -0,0 +1,15 @@
|
||||
struct this { uint a; }
|
||||
struct super { uint b; }
|
||||
struct _ { uint c; }
|
||||
|
||||
contract C {
|
||||
this a;
|
||||
super b;
|
||||
_ c;
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 3726: (0-23): The name "this" is reserved.
|
||||
// DeclarationError 3726: (24-48): The name "super" is reserved.
|
||||
// DeclarationError 3726: (49-69): The name "_" is reserved.
|
||||
// Warning 2319: (0-23): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (24-48): This declaration shadows a builtin symbol.
|
@ -10,3 +10,4 @@ contract C {
|
||||
_;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
|
@ -14,4 +14,6 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 3726: (67-73): The name "_" is reserved.
|
||||
// DeclarationError 3726: (154-160): The name "_" is reserved.
|
||||
// DeclarationError 7576: (230-231): Undeclared identifier.
|
||||
|
@ -16,3 +16,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 3726: (77-92): The name "_" is reserved.
|
||||
|
@ -0,0 +1,30 @@
|
||||
uint constant this = 1;
|
||||
uint constant super = 2;
|
||||
uint constant _ = 3;
|
||||
contract C {
|
||||
address this;
|
||||
int super;
|
||||
mapping (address => address) _;
|
||||
}
|
||||
|
||||
contract D {
|
||||
address[] this;
|
||||
struct _ { uint super; }
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 3726: (0-22): The name "this" is reserved.
|
||||
// DeclarationError 3726: (24-47): The name "super" is reserved.
|
||||
// DeclarationError 3726: (49-68): The name "_" is reserved.
|
||||
// DeclarationError 3726: (84-96): The name "this" is reserved.
|
||||
// DeclarationError 3726: (99-108): The name "super" is reserved.
|
||||
// DeclarationError 3726: (111-141): The name "_" is reserved.
|
||||
// DeclarationError 3726: (160-174): The name "this" is reserved.
|
||||
// DeclarationError 3726: (177-201): The name "_" is reserved.
|
||||
// DeclarationError 3726: (188-198): The name "super" is reserved.
|
||||
// Warning 2519: (84-96): This declaration shadows an existing declaration.
|
||||
// Warning 2519: (99-108): This declaration shadows an existing declaration.
|
||||
// Warning 2519: (111-141): This declaration shadows an existing declaration.
|
||||
// Warning 2519: (160-174): This declaration shadows an existing declaration.
|
||||
// Warning 2519: (177-201): This declaration shadows an existing declaration.
|
||||
// Warning 2319: (0-22): This declaration shadows a builtin symbol.
|
||||
// Warning 2319: (24-47): This declaration shadows a builtin symbol.
|
Loading…
Reference in New Issue
Block a user