From 0647039864120b6a267f072870770975c4dd24e1 Mon Sep 17 00:00:00 2001 From: hrkrshnn Date: Mon, 16 Aug 2021 14:43:05 +0200 Subject: [PATCH] DeclarationTypeChecker for UserDefinedValueTypes - Checks for repetitions. - Assigns types. - Checks if the 'actual type' is an elementary type name. - Checks if the 'actual type' is a value type. Also added tests. --- .../analysis/DeclarationTypeChecker.cpp | 26 +++++++++++++++++++ libsolidity/analysis/DeclarationTypeChecker.h | 1 + .../userDefinedValueType/all_value_types.sol | 12 +++++++++ .../userDefinedValueType/conversion_err.sol | 6 +++++ .../name_conflict_contract_warning.sol | 6 +++++ .../name_conflict_err.sol | 9 +++++++ .../non_value_type_bytes.sol | 3 +++ .../non_value_type_contract_err.sol | 4 +++ .../non_value_type_function_err.sol | 3 +++ .../non_value_type_mapping_err.sol | 3 +++ .../non_value_type_string_err.sol | 3 +++ .../non_value_type_struct_err.sol | 7 +++++ .../userDefinedValueType/recursive_err.sol | 4 +++ .../recursive_function_paramter_err.sol | 3 +++ .../userDefinedValueType/reference.sol | 13 ++++++++++ .../userDefinedValueType/repetition_err.sol | 7 +++++ .../self_reference_err.sol | 3 +++ 17 files changed, 113 insertions(+) create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/all_value_types.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/conversion_err.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/name_conflict_contract_warning.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/name_conflict_err.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_bytes.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_contract_err.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_function_err.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_mapping_err.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_string_err.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_struct_err.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/recursive_err.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/recursive_function_paramter_err.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/reference.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/repetition_err.sol create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/self_reference_err.sol diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index c184e11df..f67d7d501 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -140,6 +140,30 @@ bool DeclarationTypeChecker::visit(StructDefinition const& _struct) return false; } +void DeclarationTypeChecker::endVisit(UserDefinedValueTypeDefinition const& _userDefined) +{ + TypeName const* typeName = _userDefined.underlyingType(); + solAssert(typeName, ""); + if (!dynamic_cast(typeName)) + m_errorReporter.fatalTypeError( + 8657_error, + typeName->location(), + "The underlying type for a user defined value type has to be an elementary value type." + ); + + Type const* type = typeName->annotation().type; + solAssert(type, ""); + solAssert(!dynamic_cast(type), ""); + if (!type->isValueType()) + m_errorReporter.typeError( + 8129_error, + _userDefined.location(), + "The underlying type of the user defined value type \"" + + _userDefined.name() + + "\" is not a value type." + ); +} + void DeclarationTypeChecker::endVisit(UserDefinedTypeName const& _typeName) { if (_typeName.annotation().type) @@ -158,6 +182,8 @@ void DeclarationTypeChecker::endVisit(UserDefinedTypeName const& _typeName) _typeName.annotation().type = TypeProvider::enumType(*enumDef); else if (ContractDefinition const* contract = dynamic_cast(declaration)) _typeName.annotation().type = TypeProvider::contract(*contract); + else if (auto userDefinedValueType = dynamic_cast(declaration)) + _typeName.annotation().type = TypeProvider::userDefinedValueType(*userDefinedValueType); else { _typeName.annotation().type = TypeProvider::emptyTuple(); diff --git a/libsolidity/analysis/DeclarationTypeChecker.h b/libsolidity/analysis/DeclarationTypeChecker.h index d327d4296..cb887c845 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.h +++ b/libsolidity/analysis/DeclarationTypeChecker.h @@ -60,6 +60,7 @@ private: void endVisit(VariableDeclaration const& _variable) override; bool visit(EnumDefinition const& _enum) override; bool visit(StructDefinition const& _struct) override; + void endVisit(UserDefinedValueTypeDefinition const& _userDefined) override; bool visit(UsingForDirective const& _usingForDirective) override; bool visit(InheritanceSpecifier const& _inheritanceSpecifier) override; diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/all_value_types.sol b/test/libsolidity/syntaxTests/userDefinedValueType/all_value_types.sol new file mode 100644 index 000000000..3388c1976 --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/all_value_types.sol @@ -0,0 +1,12 @@ +type MyAddress is address; +type MyAddressPayable is address payable; +type MyInt is int; +type MyUInt is uint; +type MyInt128 is int128; +type MyUInt128 is uint128; +// TODO add fixed point type, when it's implemented +type MyFixedBytes32 is bytes32; +type MyFixedBytes1 is bytes1; +type MyBool is bool; +/// test to see if having NatSpec causes issues +type redundantNatSpec is bytes2; diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/conversion_err.sol b/test/libsolidity/syntaxTests/userDefinedValueType/conversion_err.sol new file mode 100644 index 000000000..33c81aee5 --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/conversion_err.sol @@ -0,0 +1,6 @@ +type MyAddress is address; +function f() { + MyAddress a = MyAddress(5, 2); +} +// ---- +// TypeError 2558: (60-75): Exactly one argument expected for explicit type conversion. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/name_conflict_contract_warning.sol b/test/libsolidity/syntaxTests/userDefinedValueType/name_conflict_contract_warning.sol new file mode 100644 index 000000000..8c5306bc4 --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/name_conflict_contract_warning.sol @@ -0,0 +1,6 @@ +type MyAddress is address; +contract C { + type MyAddress is address; +} +// ---- +// Warning 2519: (44-70): This declaration shadows an existing declaration. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/name_conflict_err.sol b/test/libsolidity/syntaxTests/userDefinedValueType/name_conflict_err.sol new file mode 100644 index 000000000..6573111ea --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/name_conflict_err.sol @@ -0,0 +1,9 @@ +type MyInt is int; +type MyInt is address; +contract C { + type MyAddress is address; + type MyAddress is address; +} +// ---- +// DeclarationError 2333: (19-41): Identifier already declared. +// DeclarationError 2333: (90-116): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_bytes.sol b/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_bytes.sol new file mode 100644 index 000000000..2bb6c5809 --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_bytes.sol @@ -0,0 +1,3 @@ +type MyBytes is bytes; +// ---- +// TypeError 8129: (0-22): The underlying type of the user defined value type "MyBytes" is not a value type. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_contract_err.sol b/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_contract_err.sol new file mode 100644 index 000000000..5a86e92f9 --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_contract_err.sol @@ -0,0 +1,4 @@ +contract C {} +type MyContract is C; +// ---- +// TypeError 8657: (33-34): The underlying type for a user defined value type has to be an elementary value type. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_function_err.sol b/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_function_err.sol new file mode 100644 index 000000000..78d9c7043 --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_function_err.sol @@ -0,0 +1,3 @@ +type MyFunction is function(uint) returns (uint); +// ---- +// TypeError 8657: (19-49): The underlying type for a user defined value type has to be an elementary value type. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_mapping_err.sol b/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_mapping_err.sol new file mode 100644 index 000000000..9f894c521 --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_mapping_err.sol @@ -0,0 +1,3 @@ +type MyInt is mapping(uint => uint); +// ---- +// TypeError 8657: (14-35): The underlying type for a user defined value type has to be an elementary value type. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_string_err.sol b/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_string_err.sol new file mode 100644 index 000000000..b44b23bdb --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_string_err.sol @@ -0,0 +1,3 @@ +type MyString is string; +// ---- +// TypeError 8129: (0-24): The underlying type of the user defined value type "MyString" is not a value type. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_struct_err.sol b/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_struct_err.sol new file mode 100644 index 000000000..3a713a887 --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/non_value_type_struct_err.sol @@ -0,0 +1,7 @@ +struct S {uint x;} + +contract C { + type MyType is S; +} +// ---- +// TypeError 8657: (52-53): The underlying type for a user defined value type has to be an elementary value type. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/recursive_err.sol b/test/libsolidity/syntaxTests/userDefinedValueType/recursive_err.sol new file mode 100644 index 000000000..4130edde5 --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/recursive_err.sol @@ -0,0 +1,4 @@ +type MyInt1 is MyInt2; +type MyInt2 is MyInt1; +// ---- +// TypeError 8657: (15-21): The underlying type for a user defined value type has to be an elementary value type. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/recursive_function_paramter_err.sol b/test/libsolidity/syntaxTests/userDefinedValueType/recursive_function_paramter_err.sol new file mode 100644 index 000000000..52e99311e --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/recursive_function_paramter_err.sol @@ -0,0 +1,3 @@ +type MyFunction is function(MyFunction) external returns(MyFunction); +// ---- +// TypeError 8657: (19-69): The underlying type for a user defined value type has to be an elementary value type. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/reference.sol b/test/libsolidity/syntaxTests/userDefinedValueType/reference.sol new file mode 100644 index 000000000..81a1ae8af --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/reference.sol @@ -0,0 +1,13 @@ +library L { + type MyInt is int; +} + +contract C { + L.MyInt a; + type MyInt is int8; +} + +contract D is C { + C.MyInt b; + L.MyInt c; +} diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/repetition_err.sol b/test/libsolidity/syntaxTests/userDefinedValueType/repetition_err.sol new file mode 100644 index 000000000..d9fc18d7f --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/repetition_err.sol @@ -0,0 +1,7 @@ +type MyInt is int; +type MyInt is int; +type MyAddress is address; +type MyAddress is uint; +// ---- +// DeclarationError 2333: (19-37): Identifier already declared. +// DeclarationError 2333: (65-88): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/self_reference_err.sol b/test/libsolidity/syntaxTests/userDefinedValueType/self_reference_err.sol new file mode 100644 index 000000000..20c657c73 --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/self_reference_err.sol @@ -0,0 +1,3 @@ +type MyInt is MyInt; +// ---- +// TypeError 8657: (14-19): The underlying type for a user defined value type has to be an elementary value type.