mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Return a type error when an enum has more than 256 members
This commit is contained in:
parent
472538c915
commit
1bf700e088
@ -8,6 +8,7 @@ Breaking Changes:
|
|||||||
* Type Checker: Function call options can only be given once.
|
* Type Checker: Function call options can only be given once.
|
||||||
* Type System: Unary negation can only be used on signed integers, not on unsigned integers.
|
* Type System: Unary negation can only be used on signed integers, not on unsigned integers.
|
||||||
* Type System: Disallow explicit conversions from negative literals and literals larger than ``type(uint160).max`` to ``address`` type.
|
* Type System: Disallow explicit conversions from negative literals and literals larger than ``type(uint160).max`` to ``address`` type.
|
||||||
|
* Type System: Disallow enums with more than 256 members.
|
||||||
* Parser: Exponentiation is right associative. ``a**b**c`` is parsed as ``a**(b**c)``.
|
* Parser: Exponentiation is right associative. ``a**b**c`` is parsed as ``a**(b**c)``.
|
||||||
* Code Generator: Use ``revert`` with error signature ``Panic(uint256)`` and error codes instead of invalid opcode on failing assertions.
|
* 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 integer type is as strict as implicit conversions.
|
||||||
|
@ -54,3 +54,7 @@ New Restrictions
|
|||||||
* The global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4`` have been removed.
|
* The global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4`` have been removed.
|
||||||
|
|
||||||
These are low-level functions that were largely unused. Their behaviour can be accessed from inline assembly.
|
These are low-level functions that were largely unused. Their behaviour can be accessed from inline assembly.
|
||||||
|
|
||||||
|
* ``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``.
|
||||||
|
@ -109,14 +109,15 @@ them.
|
|||||||
+-------------------------------+-----------------------------------------------------------------------------+
|
+-------------------------------+-----------------------------------------------------------------------------+
|
||||||
|:ref:`contract<contracts>` |``address`` |
|
|:ref:`contract<contracts>` |``address`` |
|
||||||
+-------------------------------+-----------------------------------------------------------------------------+
|
+-------------------------------+-----------------------------------------------------------------------------+
|
||||||
|:ref:`enum<enums>` |smallest ``uint`` type that is large enough to hold all values |
|
|:ref:`enum<enums>` |``uint8`` |
|
||||||
| | |
|
|
||||||
| |For example, an ``enum`` of 256 values or less is mapped to ``uint8`` and |
|
|
||||||
| |an ``enum`` of 256 values is mapped to ``uint16``. |
|
|
||||||
+-------------------------------+-----------------------------------------------------------------------------+
|
+-------------------------------+-----------------------------------------------------------------------------+
|
||||||
|:ref:`struct<structs>` |``tuple`` |
|
|:ref:`struct<structs>` |``tuple`` |
|
||||||
+-------------------------------+-----------------------------------------------------------------------------+
|
+-------------------------------+-----------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
Before version ``0.8.0`` enums could have more than 256 members and were represented by the
|
||||||
|
smallest integer type just big enough to hold the value of any member.
|
||||||
|
|
||||||
Design Criteria for the Encoding
|
Design Criteria for the Encoding
|
||||||
================================
|
================================
|
||||||
|
|
||||||
|
@ -565,6 +565,7 @@ to and from all integer types but implicit conversion is not allowed. The expli
|
|||||||
from integer checks at runtime that the value lies inside the range of the enum and causes a
|
from integer checks at runtime that the value lies inside the range of the enum and causes a
|
||||||
:ref:`Panic error<assert-and-require>` otherwise.
|
:ref:`Panic error<assert-and-require>` otherwise.
|
||||||
Enums require at least one member, and its default value when declared is the first member.
|
Enums require at least one member, and its default value when declared is the first member.
|
||||||
|
Enums cannot have more than 256 members.
|
||||||
|
|
||||||
The data representation is the same as for enums in C: The options are represented by
|
The data representation is the same as for enums in C: The options are represented by
|
||||||
subsequent unsigned integer values starting from ``0``.
|
subsequent unsigned integer values starting from ``0``.
|
||||||
@ -586,9 +587,7 @@ subsequent unsigned integer values starting from ``0``.
|
|||||||
|
|
||||||
// Since enum types are not part of the ABI, the signature of "getChoice"
|
// Since enum types are not part of the ABI, the signature of "getChoice"
|
||||||
// will automatically be changed to "getChoice() returns (uint8)"
|
// will automatically be changed to "getChoice() returns (uint8)"
|
||||||
// for all matters external to Solidity. The integer type used is just
|
// for all matters external to Solidity.
|
||||||
// large enough to hold all enum values, i.e. if you have more than 256 values,
|
|
||||||
// `uint16` will be used and so on.
|
|
||||||
function getChoice() public view returns (ActionChoices) {
|
function getChoice() public view returns (ActionChoices) {
|
||||||
return choice;
|
return choice;
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,18 @@ bool DeclarationTypeChecker::visit(ElementaryTypeName const& _typeName)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DeclarationTypeChecker::visit(EnumDefinition const& _enum)
|
||||||
|
{
|
||||||
|
if (_enum.members().size() > 256)
|
||||||
|
m_errorReporter.declarationError(
|
||||||
|
1611_error,
|
||||||
|
_enum.location(),
|
||||||
|
"Enum with more than 256 members is not allowed."
|
||||||
|
);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool DeclarationTypeChecker::visit(StructDefinition const& _struct)
|
bool DeclarationTypeChecker::visit(StructDefinition const& _struct)
|
||||||
{
|
{
|
||||||
if (_struct.annotation().recursive.has_value())
|
if (_struct.annotation().recursive.has_value())
|
||||||
|
@ -59,6 +59,7 @@ private:
|
|||||||
void endVisit(Mapping const& _mapping) override;
|
void endVisit(Mapping const& _mapping) override;
|
||||||
void endVisit(ArrayTypeName const& _typeName) override;
|
void endVisit(ArrayTypeName const& _typeName) override;
|
||||||
void endVisit(VariableDeclaration const& _variable) override;
|
void endVisit(VariableDeclaration const& _variable) override;
|
||||||
|
bool visit(EnumDefinition const& _enum) override;
|
||||||
bool visit(StructDefinition const& _struct) override;
|
bool visit(StructDefinition const& _struct) override;
|
||||||
bool visit(UsingForDirective const& _usingForDirective) override;
|
bool visit(UsingForDirective const& _usingForDirective) override;
|
||||||
bool visit(InheritanceSpecifier const& _inheritanceSpecifier) override;
|
bool visit(InheritanceSpecifier const& _inheritanceSpecifier) override;
|
||||||
|
@ -672,7 +672,7 @@ ASTPointer<EnumDefinition> Parser::parseEnumDefinition()
|
|||||||
fatalParserError(1612_error, "Expected identifier after ','");
|
fatalParserError(1612_error, "Expected identifier after ','");
|
||||||
}
|
}
|
||||||
if (members.empty())
|
if (members.empty())
|
||||||
parserError(3147_error, "enum with no members is not allowed.");
|
parserError(3147_error, "Enum with no members is not allowed.");
|
||||||
|
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
expectToken(Token::RBrace);
|
expectToken(Token::RBrace);
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
enum E {
|
||||||
|
E000, E001, E002, E003, E004, E005, E006, E007, E008, E009,
|
||||||
|
E010, E011, E012, E013, E014, E015, E016, E017, E018, E019,
|
||||||
|
E020, E021, E022, E023, E024, E025, E026, E027, E028, E029,
|
||||||
|
E030, E031, E032, E033, E034, E035, E036, E037, E038, E039,
|
||||||
|
E040, E041, E042, E043, E044, E045, E046, E047, E048, E049,
|
||||||
|
E050, E051, E052, E053, E054, E055, E056, E057, E058, E059,
|
||||||
|
E060, E061, E062, E063, E064, E065, E066, E067, E068, E069,
|
||||||
|
E070, E071, E072, E073, E074, E075, E076, E077, E078, E079,
|
||||||
|
E080, E081, E082, E083, E084, E085, E086, E087, E088, E089,
|
||||||
|
E090, E091, E092, E093, E094, E095, E096, E097, E098, E099,
|
||||||
|
E100, E101, E102, E103, E104, E105, E106, E107, E108, E109,
|
||||||
|
E110, E111, E112, E113, E114, E115, E116, E117, E118, E119,
|
||||||
|
E120, E121, E122, E123, E124, E125, E126, E127, E128, E129,
|
||||||
|
E130, E131, E132, E133, E134, E135, E136, E137, E138, E139,
|
||||||
|
E140, E141, E142, E143, E144, E145, E146, E147, E148, E149,
|
||||||
|
E150, E151, E152, E153, E154, E155, E156, E157, E158, E159,
|
||||||
|
E160, E161, E162, E163, E164, E165, E166, E167, E168, E169,
|
||||||
|
E170, E171, E172, E173, E174, E175, E176, E177, E178, E179,
|
||||||
|
E180, E181, E182, E183, E184, E185, E186, E187, E188, E189,
|
||||||
|
E190, E191, E192, E193, E194, E195, E196, E197, E198, E199,
|
||||||
|
E200, E201, E202, E203, E204, E205, E206, E207, E208, E209,
|
||||||
|
E210, E211, E212, E213, E214, E215, E216, E217, E218, E219,
|
||||||
|
E220, E221, E222, E223, E224, E225, E226, E227, E228, E229,
|
||||||
|
E230, E231, E232, E233, E234, E235, E236, E237, E238, E239,
|
||||||
|
E240, E241, E242, E243, E244, E245, E246, E247, E248, E249,
|
||||||
|
E250, E251, E252, E253, E254, E255
|
||||||
|
}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
function getMinMax() public returns (E, E) {
|
||||||
|
return (E.E000, E.E255);
|
||||||
|
}
|
||||||
|
|
||||||
|
function intToEnum(uint8 _i) public returns (E) {
|
||||||
|
return E(_i);
|
||||||
|
}
|
||||||
|
|
||||||
|
function enumToInt(E _e) public returns (uint8) {
|
||||||
|
return uint8(_e);
|
||||||
|
}
|
||||||
|
|
||||||
|
function decodeEnum(bytes memory data) public returns (E) {
|
||||||
|
(E e) = abi.decode(data, (E));
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
|
// ----
|
||||||
|
// getMinMax() -> 0, 255
|
||||||
|
// intToEnum(uint8): 0 -> 0
|
||||||
|
// intToEnum(uint8): 255 -> 255
|
||||||
|
// enumToInt(uint8): 0 -> 0
|
||||||
|
// enumToInt(uint8): 255 -> 255
|
||||||
|
// enumToInt(uint8): 256 -> FAILURE
|
||||||
|
// decodeEnum(bytes): 0x20, 32, 0 -> 0
|
||||||
|
// decodeEnum(bytes): 0x20, 32, 255 -> 255
|
||||||
|
// decodeEnum(bytes): 0x20, 32, 256 -> FAILURE
|
@ -0,0 +1,30 @@
|
|||||||
|
enum E {
|
||||||
|
E000, E001, E002, E003, E004, E005, E006, E007, E008, E009,
|
||||||
|
E010, E011, E012, E013, E014, E015, E016, E017, E018, E019,
|
||||||
|
E020, E021, E022, E023, E024, E025, E026, E027, E028, E029,
|
||||||
|
E030, E031, E032, E033, E034, E035, E036, E037, E038, E039,
|
||||||
|
E040, E041, E042, E043, E044, E045, E046, E047, E048, E049,
|
||||||
|
E050, E051, E052, E053, E054, E055, E056, E057, E058, E059,
|
||||||
|
E060, E061, E062, E063, E064, E065, E066, E067, E068, E069,
|
||||||
|
E070, E071, E072, E073, E074, E075, E076, E077, E078, E079,
|
||||||
|
E080, E081, E082, E083, E084, E085, E086, E087, E088, E089,
|
||||||
|
E090, E091, E092, E093, E094, E095, E096, E097, E098, E099,
|
||||||
|
E100, E101, E102, E103, E104, E105, E106, E107, E108, E109,
|
||||||
|
E110, E111, E112, E113, E114, E115, E116, E117, E118, E119,
|
||||||
|
E120, E121, E122, E123, E124, E125, E126, E127, E128, E129,
|
||||||
|
E130, E131, E132, E133, E134, E135, E136, E137, E138, E139,
|
||||||
|
E140, E141, E142, E143, E144, E145, E146, E147, E148, E149,
|
||||||
|
E150, E151, E152, E153, E154, E155, E156, E157, E158, E159,
|
||||||
|
E160, E161, E162, E163, E164, E165, E166, E167, E168, E169,
|
||||||
|
E170, E171, E172, E173, E174, E175, E176, E177, E178, E179,
|
||||||
|
E180, E181, E182, E183, E184, E185, E186, E187, E188, E189,
|
||||||
|
E190, E191, E192, E193, E194, E195, E196, E197, E198, E199,
|
||||||
|
E200, E201, E202, E203, E204, E205, E206, E207, E208, E209,
|
||||||
|
E210, E211, E212, E213, E214, E215, E216, E217, E218, E219,
|
||||||
|
E220, E221, E222, E223, E224, E225, E226, E227, E228, E229,
|
||||||
|
E230, E231, E232, E233, E234, E235, E236, E237, E238, E239,
|
||||||
|
E240, E241, E242, E243, E244, E245, E246, E247, E248, E249,
|
||||||
|
E250, E251, E252, E253, E254, E255, E256
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// DeclarationError 1611: (0-1655): Enum with more than 256 members is not allowed.
|
@ -2,4 +2,4 @@ contract c {
|
|||||||
enum foo { }
|
enum foo { }
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// ParserError 3147: (25-26): enum with no members is not allowed.
|
// ParserError 3147: (25-26): Enum with no members is not allowed.
|
||||||
|
Loading…
Reference in New Issue
Block a user