From b0d3412fa9bc2cc9b3fc69ea0346c698601d6d91 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Tue, 2 Feb 2021 17:31:31 +0100 Subject: [PATCH 1/4] Fixes missing EnumValue declaration in nativeMembers. --- libsolidity/ast/Types.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 8197b4b26..92edcac1e 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -3725,7 +3725,7 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons EnumDefinition const& enumDef = dynamic_cast(*m_actualType).enumDefinition(); auto enumType = TypeProvider::enumType(enumDef); for (ASTPointer const& enumValue: enumDef.members()) - members.emplace_back(enumValue->name(), enumType); + members.emplace_back(enumValue->name(), enumType, enumValue.get()); } return members; } From 9ca389d6cd82410bcc887fd42ab2318b90307608 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Mon, 8 Feb 2021 13:33:39 +0100 Subject: [PATCH 2/4] MemberList.Member's last argument (declaration) made mandatory to avoid accidental missing out during construction. --- libsolidity/ast/Types.cpp | 38 ++++++++++++++++++------------ libsolidity/ast/Types.h | 12 ++++++---- test/libsolidity/SolidityTypes.cpp | 14 +++++------ 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 92edcac1e..182b2b72b 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -111,6 +111,13 @@ util::Result transformParametersToExternal(TypePointers const& _pa } +MemberList::Member::Member(Declaration const* _declaration, Type const* _type): + name(_declaration->name()), + type(_type), + declaration(_declaration) +{ +} + void Type::clearCache() const { m_members.clear(); @@ -365,7 +372,7 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _sc FunctionTypePointer fun = dynamic_cast(*function->typeViaContractName()).asBoundFunction(); if (_type.isImplicitlyConvertibleTo(*fun->selfType())) - members.emplace_back(function->name(), fun, function); + members.emplace_back(function, fun); } } @@ -1985,9 +1992,8 @@ MemberList::MemberMap ContractType::nativeMembers(ASTNode const*) const if (!m_contract.isLibrary()) for (auto const& it: m_contract.interfaceFunctions()) members.emplace_back( - it.second->declaration().name(), - it.second->asExternallyCallableFunction(m_contract.isLibrary()), - &it.second->declaration() + &it.second->declaration(), + it.second->asExternallyCallableFunction(m_contract.isLibrary()) ); return members; @@ -2213,9 +2219,8 @@ MemberList::MemberMap StructType::nativeMembers(ASTNode const*) const solAssert(type, ""); solAssert(!(location() != DataLocation::Storage && type->containsNestedMapping()), ""); members.emplace_back( - variable->name(), - copyForLocationIfReference(type), - variable.get() + variable.get(), + copyForLocationIfReference(type) ); } return members; @@ -3687,7 +3692,7 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons break; } if (!functionWithEqualArgumentsFound) - members.emplace_back(function->name(), functionType, function); + members.emplace_back(function, functionType); } } else @@ -3708,15 +3713,15 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons auto const* functionDefinition = dynamic_cast(declaration); functionDefinition && !functionDefinition->isImplemented() ) - members.emplace_back(declaration->name(), declaration->typeViaContractName(), declaration); + members.emplace_back(declaration, declaration->typeViaContractName()); else - members.emplace_back(declaration->name(), declaration->type(), declaration); + members.emplace_back(declaration, declaration->type()); } else if ( (contract.isLibrary() && declaration->isVisibleAsLibraryMember()) || declaration->isVisibleViaContractTypeAccess() ) - members.emplace_back(declaration->name(), declaration->typeViaContractName(), declaration); + members.emplace_back(declaration, declaration->typeViaContractName()); } } } @@ -3725,7 +3730,7 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons EnumDefinition const& enumDef = dynamic_cast(*m_actualType).enumDefinition(); auto enumType = TypeProvider::enumType(enumDef); for (ASTPointer const& enumValue: enumDef.members()) - members.emplace_back(enumValue->name(), enumType, enumValue.get()); + members.emplace_back(enumValue.get(), enumType); } return members; } @@ -3801,9 +3806,12 @@ bool ModuleType::operator==(Type const& _other) const MemberList::MemberMap ModuleType::nativeMembers(ASTNode const*) const { MemberList::MemberMap symbols; - for (auto const& symbolName: *m_sourceUnit.annotation().exportedSymbols) - for (Declaration const* symbol: symbolName.second) - symbols.emplace_back(symbolName.first, symbol->type(), symbol); + for (auto const& [name, declarations]: *m_sourceUnit.annotation().exportedSymbols) + for (Declaration const* symbol: declarations) + { + solAssert(name == symbol->name(), ""); + symbols.emplace_back(symbol, symbol->type()); + } return symbols; } diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 839e8ef01..0414ea783 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -100,15 +100,19 @@ class MemberList public: struct Member { - Member(std::string _name, Type const* _type, Declaration const* _declaration = nullptr): - name(std::move(_name)), + /// Manual constructor for members that are not taken from a declaration. + Member(char const* _name, Type const* _type): + name(_name), type(_type), - declaration(_declaration) + declaration(nullptr) { } + /// Constructs a Member with the name extracted from @p _declaration's name. + Member(Declaration const* _declaration, Type const* _type); + std::string name; - Type const* type; + Type const* type = nullptr; Declaration const* declaration = nullptr; }; diff --git a/test/libsolidity/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp index be711467e..464693c67 100644 --- a/test/libsolidity/SolidityTypes.cpp +++ b/test/libsolidity/SolidityTypes.cpp @@ -78,9 +78,9 @@ BOOST_AUTO_TEST_CASE(ufixed_types) BOOST_AUTO_TEST_CASE(storage_layout_simple) { MemberList members(MemberList::MemberMap({ - {string("first"), TypeProvider::fromElementaryTypeName("uint128")}, - {string("second"), TypeProvider::fromElementaryTypeName("uint120")}, - {string("wraps"), TypeProvider::fromElementaryTypeName("uint16")} + {"first", TypeProvider::fromElementaryTypeName("uint128")}, + {"second", TypeProvider::fromElementaryTypeName("uint120")}, + {"wraps", TypeProvider::fromElementaryTypeName("uint16")} })); BOOST_REQUIRE_EQUAL(u256(2), members.storageSize()); BOOST_REQUIRE(members.memberStorageOffset("first") != nullptr); @@ -94,13 +94,13 @@ BOOST_AUTO_TEST_CASE(storage_layout_simple) BOOST_AUTO_TEST_CASE(storage_layout_mapping) { MemberList members(MemberList::MemberMap({ - {string("first"), TypeProvider::fromElementaryTypeName("uint128")}, - {string("second"), TypeProvider::mapping( + {"first", TypeProvider::fromElementaryTypeName("uint128")}, + {"second", TypeProvider::mapping( TypeProvider::fromElementaryTypeName("uint8"), TypeProvider::fromElementaryTypeName("uint8") )}, - {string("third"), TypeProvider::fromElementaryTypeName("uint16")}, - {string("final"), TypeProvider::mapping( + {"third", TypeProvider::fromElementaryTypeName("uint16")}, + {"final", TypeProvider::mapping( TypeProvider::fromElementaryTypeName("uint8"), TypeProvider::fromElementaryTypeName("uint8") )}, From f4790971ae583dd4d720befa4e842f15ed49a53e Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 11 Feb 2021 09:49:29 +0100 Subject: [PATCH 3/4] Add test. --- .../ASTJSON/enum_value_declaration.json | 159 ++++++++++++++++++ .../ASTJSON/enum_value_declaration.sol | 4 + .../enum_value_declaration_parseOnly.json | 120 +++++++++++++ 3 files changed, 283 insertions(+) create mode 100644 test/libsolidity/ASTJSON/enum_value_declaration.json create mode 100644 test/libsolidity/ASTJSON/enum_value_declaration.sol create mode 100644 test/libsolidity/ASTJSON/enum_value_declaration_parseOnly.json diff --git a/test/libsolidity/ASTJSON/enum_value_declaration.json b/test/libsolidity/ASTJSON/enum_value_declaration.json new file mode 100644 index 000000000..fc8506c2a --- /dev/null +++ b/test/libsolidity/ASTJSON/enum_value_declaration.json @@ -0,0 +1,159 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "A": + [ + 3 + ], + "f": + [ + 13 + ] + }, + "id": 14, + "nodeType": "SourceUnit", + "nodes": + [ + { + "canonicalName": "A", + "id": 3, + "members": + [ + { + "id": 1, + "name": "X", + "nameLocation": "9:1:1", + "nodeType": "EnumValue", + "src": "9:1:1" + }, + { + "id": 2, + "name": "Y", + "nameLocation": "12:1:1", + "nodeType": "EnumValue", + "src": "12:1:1" + } + ], + "name": "A", + "nameLocation": "5:1:1", + "nodeType": "EnumDefinition", + "src": "0:15:1" + }, + { + "body": + { + "id": 12, + "nodeType": "Block", + "src": "46:15:1", + "statements": + [ + { + "expression": + { + "expression": + { + "id": 9, + "name": "A", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3, + "src": "55:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_enum$_A_$3_$", + "typeString": "type(enum A)" + } + }, + "id": 10, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "X", + "nodeType": "MemberAccess", + "referencedDeclaration": 1, + "src": "55:3:1", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_A_$3", + "typeString": "enum A" + } + }, + "functionReturnParameters": 8, + "id": 11, + "nodeType": "Return", + "src": "48:10:1" + } + ] + }, + "id": 13, + "implemented": true, + "kind": "freeFunction", + "modifiers": [], + "name": "f", + "nameLocation": "25:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 4, + "nodeType": "ParameterList", + "parameters": [], + "src": "26:2:1" + }, + "returnParameters": + { + "id": 8, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 7, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 13, + "src": "43:1:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_A_$3", + "typeString": "enum A" + }, + "typeName": + { + "id": 6, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 5, + "name": "A", + "nodeType": "IdentifierPath", + "referencedDeclaration": 3, + "src": "43:1:1" + }, + "referencedDeclaration": 3, + "src": "43:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_A_$3", + "typeString": "enum A" + } + }, + "visibility": "internal" + } + ], + "src": "42:3:1" + }, + "scope": 14, + "src": "16:45:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + } + ], + "src": "0:62:1" +} diff --git a/test/libsolidity/ASTJSON/enum_value_declaration.sol b/test/libsolidity/ASTJSON/enum_value_declaration.sol new file mode 100644 index 000000000..1fb98b3e8 --- /dev/null +++ b/test/libsolidity/ASTJSON/enum_value_declaration.sol @@ -0,0 +1,4 @@ +enum A { X, Y } +function f() pure returns (A) { return A.X; } + +// ---- diff --git a/test/libsolidity/ASTJSON/enum_value_declaration_parseOnly.json b/test/libsolidity/ASTJSON/enum_value_declaration_parseOnly.json new file mode 100644 index 000000000..f99b7cb87 --- /dev/null +++ b/test/libsolidity/ASTJSON/enum_value_declaration_parseOnly.json @@ -0,0 +1,120 @@ +{ + "absolutePath": "a", + "id": 14, + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 3, + "members": + [ + { + "id": 1, + "name": "X", + "nameLocation": "9:1:1", + "nodeType": "EnumValue", + "src": "9:1:1" + }, + { + "id": 2, + "name": "Y", + "nameLocation": "12:1:1", + "nodeType": "EnumValue", + "src": "12:1:1" + } + ], + "name": "A", + "nameLocation": "5:1:1", + "nodeType": "EnumDefinition", + "src": "0:15:1" + }, + { + "body": + { + "id": 12, + "nodeType": "Block", + "src": "46:15:1", + "statements": + [ + { + "expression": + { + "expression": + { + "id": 9, + "name": "A", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "src": "55:1:1", + "typeDescriptions": {} + }, + "id": 10, + "memberName": "X", + "nodeType": "MemberAccess", + "src": "55:3:1", + "typeDescriptions": {} + }, + "id": 11, + "nodeType": "Return", + "src": "48:10:1" + } + ] + }, + "id": 13, + "implemented": true, + "kind": "freeFunction", + "modifiers": [], + "name": "f", + "nameLocation": "25:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 4, + "nodeType": "ParameterList", + "parameters": [], + "src": "26:2:1" + }, + "returnParameters": + { + "id": 8, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 7, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "src": "43:1:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": {}, + "typeName": + { + "id": 6, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 5, + "name": "A", + "nodeType": "IdentifierPath", + "src": "43:1:1" + }, + "src": "43:1:1", + "typeDescriptions": {} + }, + "visibility": "internal" + } + ], + "src": "42:3:1" + }, + "src": "16:45:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + } + ], + "src": "0:62:1" +} From 24cc3720690be85b59fb6e5733e4951c555b62a4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 11 Feb 2021 10:17:13 +0100 Subject: [PATCH 4/4] Changelog entry. --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 09b5d59d2..727465660 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,7 @@ Compiler Features: Bugfixes: * Type Checker: Fix internal error when override specifier is not a contract. * SMTChecker: Fix missing type constraints on block and transaction variables in the deployment phase. + * AST: Added ``referencedDeclaration`` for enum members. AST Changes: