Merge pull request #10255 from ethereum/this-super-underscore-reserved-identifiers

[BREAKING] Disallow declarations with name "this", "super" and "_"
This commit is contained in:
chriseth 2020-11-25 11:55:58 +01:00 committed by GitHub
commit 38f143c597
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 370 additions and 67 deletions

View File

@ -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)``.

View File

@ -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.

View File

@ -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;

View File

@ -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."
);
}

View File

@ -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

View File

@ -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"

View File

@ -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.

View File

@ -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.

View File

@ -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.

View 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.

View File

@ -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.

View 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.

View 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.

View File

@ -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.

View 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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View 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.

View File

@ -10,3 +10,4 @@ contract C {
_;
}
}
// ----

View File

@ -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.

View File

@ -16,3 +16,4 @@ contract C {
}
}
// ----
// DeclarationError 3726: (77-92): The name "_" is reserved.

View File

@ -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.