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")
|
||||
annotation.isPure = true;
|
||||
else if (magicType->kind() == MagicType::Kind::MetaType && memberName == "typehash")
|
||||
{
|
||||
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 (
|
||||
magicType->kind() == MagicType::Kind::MetaType &&
|
||||
(memberName == "min" || memberName == "max")
|
||||
|
@ -358,6 +358,7 @@ public:
|
||||
virtual std::string canonicalName() const { return toString(true); }
|
||||
virtual std::string humanReadableName() const { return toString(); }
|
||||
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
|
||||
/// or `(uint256,bytes8)[2]` for an array of structs. If @a _structsByName,
|
||||
/// structs are given by canonical name like `ContractName.StructName[2]`.
|
||||
@ -458,6 +459,7 @@ public:
|
||||
bool leftAligned() const override { return false; }
|
||||
bool isValueType() const override { return true; }
|
||||
bool nameable() const override { return true; }
|
||||
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||
|
||||
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
|
||||
|
||||
@ -503,6 +505,7 @@ public:
|
||||
bool leftAligned() const override { return false; }
|
||||
bool isValueType() const override { return true; }
|
||||
bool nameable() const override { return true; }
|
||||
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||
|
||||
std::string toString(bool _withoutDataLocation) const override;
|
||||
|
||||
@ -662,6 +665,8 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||
|
||||
std::string richIdentifier() const override;
|
||||
bool operator==(Type const& _other) const override;
|
||||
|
||||
@ -700,6 +705,7 @@ public:
|
||||
bool leftAligned() const override { return true; }
|
||||
bool isValueType() 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); }
|
||||
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
|
||||
@ -728,6 +734,7 @@ public:
|
||||
bool leftAligned() const override { return false; }
|
||||
bool isValueType() const override { return true; }
|
||||
bool nameable() const override { return true; }
|
||||
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||
|
||||
std::string toString(bool) const override { return "bool"; }
|
||||
u256 literalValue(Literal const* _literal) const override;
|
||||
@ -865,6 +872,7 @@ public:
|
||||
u256 storageSize() const override;
|
||||
bool containsNestedMapping() const override { return m_baseType->containsNestedMapping(); }
|
||||
bool nameable() const override { return true; }
|
||||
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||
|
||||
std::string toString(bool _withoutDataLocation) const override;
|
||||
std::string humanReadableName() const override;
|
||||
@ -978,6 +986,7 @@ public:
|
||||
bool leftAligned() const override { solAssert(!isSuper(), ""); return false; }
|
||||
bool isValueType() 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 canonicalName() const override;
|
||||
|
||||
@ -1040,6 +1049,7 @@ public:
|
||||
u256 storageSize() const override;
|
||||
bool containsNestedMapping() const override;
|
||||
bool nameable() const override { return true; }
|
||||
bool isEIP712AllowedStructMemberType() const override { return true; }
|
||||
std::string toString(bool _withoutDataLocation) 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