mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
added syntaxt tests and updated the TypeChecker logic.
This commit is contained in:
parent
8023619d5c
commit
84918fb01e
@ -3393,7 +3393,31 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
|
|||||||
else if (magicType->kind() == MagicType::Kind::MetaType && memberName == "interfaceId")
|
else if (magicType->kind() == MagicType::Kind::MetaType && memberName == "interfaceId")
|
||||||
annotation.isPure = true;
|
annotation.isPure = true;
|
||||||
else if (magicType->kind() == MagicType::Kind::MetaType && memberName == "typehash")
|
else if (magicType->kind() == MagicType::Kind::MetaType && memberName == "typehash")
|
||||||
|
{
|
||||||
annotation.isPure = true;
|
annotation.isPure = true;
|
||||||
|
auto accessedStructType = dynamic_cast<StructType const*>(magicType->typeArgument());
|
||||||
|
solAssert(accessedStructType, "typehash requested on a non struct type.");
|
||||||
|
|
||||||
|
if (accessedStructType->recursive()) {
|
||||||
|
m_errorReporter.typeError(
|
||||||
|
9298_error,
|
||||||
|
_memberAccess.location(),
|
||||||
|
"\"typehash\" cannot be used for recursive structs."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& member: accessedStructType->members(currentDefinitionScope()))
|
||||||
|
{
|
||||||
|
if (!member.type->isEIP712AllowedStructMemberType())
|
||||||
|
{
|
||||||
|
m_errorReporter.typeError(
|
||||||
|
9518_error,
|
||||||
|
_memberAccess.location(),
|
||||||
|
"\"typehash\" cannot be used for structs with members of \"" + member.type->humanReadableName() + "\" type."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (
|
else if (
|
||||||
magicType->kind() == MagicType::Kind::MetaType &&
|
magicType->kind() == MagicType::Kind::MetaType &&
|
||||||
(memberName == "min" || memberName == "max")
|
(memberName == "min" || memberName == "max")
|
||||||
|
@ -358,6 +358,7 @@ public:
|
|||||||
virtual std::string canonicalName() const { return toString(true); }
|
virtual std::string canonicalName() const { return toString(true); }
|
||||||
virtual std::string humanReadableName() const { return toString(); }
|
virtual std::string humanReadableName() const { return toString(); }
|
||||||
virtual std::string eip712TypeName() const { return encodingType()->toString(true); }
|
virtual std::string eip712TypeName() const { return encodingType()->toString(true); }
|
||||||
|
virtual bool isEIP712AllowedStructMemberType() const { return false; }
|
||||||
/// @returns the signature of this type in external functions, i.e. `uint256` for integers
|
/// @returns the signature of this type in external functions, i.e. `uint256` for integers
|
||||||
/// or `(uint256,bytes8)[2]` for an array of structs. If @a _structsByName,
|
/// or `(uint256,bytes8)[2]` for an array of structs. If @a _structsByName,
|
||||||
/// structs are given by canonical name like `ContractName.StructName[2]`.
|
/// structs are given by canonical name like `ContractName.StructName[2]`.
|
||||||
@ -458,6 +459,7 @@ public:
|
|||||||
bool leftAligned() const override { return false; }
|
bool leftAligned() const override { return false; }
|
||||||
bool isValueType() const override { return true; }
|
bool isValueType() const override { return true; }
|
||||||
bool nameable() const override { return true; }
|
bool nameable() const override { return true; }
|
||||||
|
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||||
|
|
||||||
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
|
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
|
||||||
|
|
||||||
@ -503,6 +505,7 @@ public:
|
|||||||
bool leftAligned() const override { return false; }
|
bool leftAligned() const override { return false; }
|
||||||
bool isValueType() const override { return true; }
|
bool isValueType() const override { return true; }
|
||||||
bool nameable() const override { return true; }
|
bool nameable() const override { return true; }
|
||||||
|
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||||
|
|
||||||
std::string toString(bool _withoutDataLocation) const override;
|
std::string toString(bool _withoutDataLocation) const override;
|
||||||
|
|
||||||
@ -662,6 +665,8 @@ public:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||||
|
|
||||||
std::string richIdentifier() const override;
|
std::string richIdentifier() const override;
|
||||||
bool operator==(Type const& _other) const override;
|
bool operator==(Type const& _other) const override;
|
||||||
|
|
||||||
@ -700,6 +705,7 @@ public:
|
|||||||
bool leftAligned() const override { return true; }
|
bool leftAligned() const override { return true; }
|
||||||
bool isValueType() const override { return true; }
|
bool isValueType() const override { return true; }
|
||||||
bool nameable() const override { return true; }
|
bool nameable() const override { return true; }
|
||||||
|
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||||
|
|
||||||
std::string toString(bool) const override { return "bytes" + util::toString(m_bytes); }
|
std::string toString(bool) const override { return "bytes" + util::toString(m_bytes); }
|
||||||
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
|
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
|
||||||
@ -728,6 +734,7 @@ public:
|
|||||||
bool leftAligned() const override { return false; }
|
bool leftAligned() const override { return false; }
|
||||||
bool isValueType() const override { return true; }
|
bool isValueType() const override { return true; }
|
||||||
bool nameable() const override { return true; }
|
bool nameable() const override { return true; }
|
||||||
|
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||||
|
|
||||||
std::string toString(bool) const override { return "bool"; }
|
std::string toString(bool) const override { return "bool"; }
|
||||||
u256 literalValue(Literal const* _literal) const override;
|
u256 literalValue(Literal const* _literal) const override;
|
||||||
@ -865,6 +872,7 @@ public:
|
|||||||
u256 storageSize() const override;
|
u256 storageSize() const override;
|
||||||
bool containsNestedMapping() const override { return m_baseType->containsNestedMapping(); }
|
bool containsNestedMapping() const override { return m_baseType->containsNestedMapping(); }
|
||||||
bool nameable() const override { return true; }
|
bool nameable() const override { return true; }
|
||||||
|
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||||
|
|
||||||
std::string toString(bool _withoutDataLocation) const override;
|
std::string toString(bool _withoutDataLocation) const override;
|
||||||
std::string humanReadableName() const override;
|
std::string humanReadableName() const override;
|
||||||
@ -978,6 +986,7 @@ public:
|
|||||||
bool leftAligned() const override { solAssert(!isSuper(), ""); return false; }
|
bool leftAligned() const override { solAssert(!isSuper(), ""); return false; }
|
||||||
bool isValueType() const override { return !isSuper(); }
|
bool isValueType() const override { return !isSuper(); }
|
||||||
bool nameable() const override { return !isSuper(); }
|
bool nameable() const override { return !isSuper(); }
|
||||||
|
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||||
std::string toString(bool _withoutDataLocation) const override;
|
std::string toString(bool _withoutDataLocation) const override;
|
||||||
std::string canonicalName() const override;
|
std::string canonicalName() const override;
|
||||||
|
|
||||||
@ -1040,6 +1049,7 @@ public:
|
|||||||
u256 storageSize() const override;
|
u256 storageSize() const override;
|
||||||
bool containsNestedMapping() const override;
|
bool containsNestedMapping() const override;
|
||||||
bool nameable() const override { return true; }
|
bool nameable() const override { return true; }
|
||||||
|
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||||
std::string toString(bool _withoutDataLocation) const override;
|
std::string toString(bool _withoutDataLocation) const override;
|
||||||
|
|
||||||
MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
|
MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
contract C {
|
||||||
|
struct S {
|
||||||
|
uint256[][10][] x;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes32 constant h = type(S).typehash;
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
contract C {
|
||||||
|
bytes32 x = type(C).typehash;
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9582: (29-45): Member "typehash" not found or not visible after argument-dependent lookup in type(contract C).
|
@ -0,0 +1,9 @@
|
|||||||
|
contract C {
|
||||||
|
enum E {
|
||||||
|
VALUE
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes32 h = type(E).typehash;
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9582: (63-79): Member "typehash" not found or not visible after argument-dependent lookup in type(enum C.E).
|
@ -0,0 +1,14 @@
|
|||||||
|
contract C {
|
||||||
|
enum E {
|
||||||
|
VALUE
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
E e;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes32 h = type(S).typehash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// TypeError 9518: (98-114): "typehash" cannot be used for structs with members of "enum C.E" type.
|
@ -0,0 +1,9 @@
|
|||||||
|
contract C {
|
||||||
|
struct S {
|
||||||
|
fixed128x18 x;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes32 h = type(S).typehash;
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9518: (74-90): "typehash" cannot be used for structs with members of "fixed128x18" type.
|
@ -0,0 +1,9 @@
|
|||||||
|
contract C {
|
||||||
|
struct S {
|
||||||
|
function(uint256) internal returns(uint256) f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes32 h = type(S).typehash;
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9518: (106-122): "typehash" cannot be used for structs with members of "function (uint256) returns (uint256)" type.
|
@ -0,0 +1,9 @@
|
|||||||
|
contract C {
|
||||||
|
struct S {
|
||||||
|
mapping (uint256 => uint256) x;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes32 h = type(S).typehash;
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9518: (92-108): "typehash" cannot be used for structs with members of "mapping(uint256 => uint256)" type.
|
@ -0,0 +1,9 @@
|
|||||||
|
contract C {
|
||||||
|
struct S {
|
||||||
|
ufixed128x18 x;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes32 h = type(S).typehash;
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9518: (75-91): "typehash" cannot be used for structs with members of "ufixed128x18" type.
|
@ -0,0 +1,10 @@
|
|||||||
|
type T is uint256;
|
||||||
|
contract C {
|
||||||
|
struct S {
|
||||||
|
T t;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes32 h = type(S).typehash;
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9518: (83-99): "typehash" cannot be used for structs with members of "T" type.
|
@ -0,0 +1,9 @@
|
|||||||
|
contract C {
|
||||||
|
struct S {
|
||||||
|
uint256 x;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f() public pure returns(bytes32) {
|
||||||
|
return type(S).typehash;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
contract C {
|
||||||
|
struct S {
|
||||||
|
S[] s;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes32 h = type(S).typehash;
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9298: (68-84): "typehash" cannot be used for recursive structs.
|
@ -0,0 +1,14 @@
|
|||||||
|
contract A {
|
||||||
|
struct S {
|
||||||
|
C.S[] s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contract C {
|
||||||
|
struct S {
|
||||||
|
A.S s;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes32 h = type(S).typehash;
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9298: (121-137): "typehash" cannot be used for recursive structs.
|
@ -0,0 +1,15 @@
|
|||||||
|
contract C {
|
||||||
|
struct S {
|
||||||
|
uint256 x;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f1(S calldata s) public pure returns(bytes32 h) {
|
||||||
|
h = type(s).typehash; // should fail
|
||||||
|
}
|
||||||
|
|
||||||
|
function f3(S calldata s) public pure returns(bytes32 h) {
|
||||||
|
h = type(S).typehash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 4259: (134-135): Invalid type for argument in the function call. An enum type, contract type, struct type or an integer type is required, but struct C.S calldata provided.
|
@ -0,0 +1,15 @@
|
|||||||
|
contract C {
|
||||||
|
struct S {
|
||||||
|
uint256 x;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f1(S memory s) public pure returns(bytes32 h) {
|
||||||
|
h = type(s).typehash; // should fail
|
||||||
|
}
|
||||||
|
|
||||||
|
function f3(S calldata s) public pure returns(bytes32 h) {
|
||||||
|
h = type(S).typehash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 4259: (132-133): Invalid type for argument in the function call. An enum type, contract type, struct type or an integer type is required, but struct C.S memory provided.
|
@ -0,0 +1,5 @@
|
|||||||
|
contract C {
|
||||||
|
bytes32 h = type(uint256).typehash;
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9582: (29-51): Member "typehash" not found or not visible after argument-dependent lookup in type(uint256).
|
@ -0,0 +1,11 @@
|
|||||||
|
contract C {
|
||||||
|
struct S {
|
||||||
|
uint256 x;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f() public view returns(bytes32) { // can be pure
|
||||||
|
return type(S).typehash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// Warning 2018: (58-155): Function state mutability can be restricted to pure
|
Loading…
Reference in New Issue
Block a user