diff --git a/Changelog.md b/Changelog.md index 80da2b2278d7..0165de0f64c8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -25,7 +25,7 @@ Bugfixes: AST Changes: - * AST: Add the ``internalFunctionID`` field to the AST nodes of functions that may be called via the internal dispatch. These IDs are always generated, but they are only used in via-IR code generation. + * AST: Add the ``internalFunctionIDs`` field to the AST nodes of contracts containing IDs of functions that may be called via the internal dispatch. The field is a map from function AST IDs to internal dispatch function IDs. These IDs are always generated, but they are only used in via-IR code generation. * AST: Add the ``usedEvents`` field to ``ContractDefinition`` which contains the AST IDs of all events emitted by the contract as well as all events defined and inherited by the contract. diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index d5087c429e2c..2573015c2734 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -168,6 +168,9 @@ struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, StructurallyDocu /// List of contracts whose bytecode is referenced by this contract, e.g. through "new". /// The Value represents the ast node that referenced the contract. std::map> contractDependencies; + + // Per-contract map from function AST IDs to internal dispatch function IDs. + std::map internalFunctionIDs; }; struct CallableDeclarationAnnotation: DeclarationAnnotation @@ -178,7 +181,6 @@ struct CallableDeclarationAnnotation: DeclarationAnnotation struct FunctionDefinitionAnnotation: CallableDeclarationAnnotation, StructurallyDocumentedAnnotation { - util::SetOnce internalFunctionID; }; struct EventDefinitionAnnotation: CallableDeclarationAnnotation, StructurallyDocumentedAnnotation diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index ad5a4f9c3ff5..e13cead11a18 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -299,6 +299,14 @@ bool ASTJsonExporter::visit(ContractDefinition const& _node) if (!_node.annotation().linearizedBaseContracts.empty()) attributes.emplace_back("linearizedBaseContracts", getContainerIds(_node.annotation().linearizedBaseContracts)); + if (!_node.annotation().internalFunctionIDs.empty()) + { + Json::Value internalFunctionIDs(Json::objectValue); + for (auto const& [functionDefinition, internalFunctionID]: _node.annotation().internalFunctionIDs) + internalFunctionIDs[to_string(functionDefinition->id())] = internalFunctionID; + attributes.emplace_back("internalFunctionIDs", std::move(internalFunctionIDs)); + } + setJsonNode(_node, "ContractDefinition", std::move(attributes)); return false; } @@ -473,9 +481,6 @@ bool ASTJsonExporter::visit(FunctionDefinition const& _node) if (!_node.annotation().baseFunctions.empty()) attributes.emplace_back(make_pair("baseFunctions", getContainerIds(_node.annotation().baseFunctions, true))); - if (_node.annotation().internalFunctionID.set()) - attributes.emplace_back("internalFunctionID", *_node.annotation().internalFunctionID); - setJsonNode(_node, "FunctionDefinition", std::move(attributes)); return false; } diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index cf11a8a02b1b..bc2f85b4aec0 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -313,7 +313,7 @@ InternalDispatchMap IRGenerator::generateInternalDispatchFunctions(ContractDefin solAssert(m_context.functionCollector().contains(IRNames::function(*function)), ""); cases.emplace_back(map{ - {"funID", to_string(*function->annotation().internalFunctionID)}, + {"funID", to_string(m_context.mostDerivedContract().annotation().internalFunctionIDs.at(function))}, {"name", IRNames::function(*function)} }); } diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 2263e11496bd..509cc28c7aa7 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -2807,7 +2807,7 @@ void IRGeneratorForStatements::assignInternalFunctionIDIfNotCalledDirectly( return; define(IRVariable(_expression).part("functionIdentifier")) << - to_string(*_referencedFunction.annotation().internalFunctionID) << + to_string(m_context.mostDerivedContract().annotation().internalFunctionIDs.at(&_referencedFunction)) << "\n"; m_context.addToInternalDispatch(_referencedFunction); } diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index ad2618bc0ac0..fa1e8ab3ea94 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1246,7 +1246,6 @@ void CompilerStack::storeContractDefinitions() void CompilerStack::annotateInternalFunctionIDs() { - uint64_t internalFunctionID = 1; for (Source const* source: m_sourceOrder) { if (!source->ast) @@ -1254,20 +1253,23 @@ void CompilerStack::annotateInternalFunctionIDs() for (ContractDefinition const* contract: ASTNode::filteredNodes(source->ast->nodes())) { + uint64_t internalFunctionID = 1; ContractDefinitionAnnotation& annotation = contract->annotation(); if (auto const* deployTimeInternalDispatch = util::valueOrNullptr((*annotation.deployedCallGraph)->edges, CallGraph::SpecialNode::InternalDispatch)) for (auto const& node: *deployTimeInternalDispatch) if (auto const* callable = get_if(&node)) if (auto const* function = dynamic_cast(*callable)) - if (!function->annotation().internalFunctionID.set()) - function->annotation().internalFunctionID = internalFunctionID++; + { + solAssert(contract->annotation().internalFunctionIDs.count(function) == 0); + contract->annotation().internalFunctionIDs[function] = internalFunctionID++; + } if (auto const* creationTimeInternalDispatch = util::valueOrNullptr((*annotation.creationCallGraph)->edges, CallGraph::SpecialNode::InternalDispatch)) for (auto const& node: *creationTimeInternalDispatch) if (auto const* callable = get_if(&node)) if (auto const* function = dynamic_cast(*callable)) // Make sure the function already got an ID since it also occurs in the deploy-time internal dispatch. - solAssert(function->annotation().internalFunctionID.set()); + solAssert(contract->annotation().internalFunctionIDs.count(function) != 0); } } } diff --git a/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.json b/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.json new file mode 100644 index 000000000000..07886a166338 --- /dev/null +++ b/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.json @@ -0,0 +1,1027 @@ +[ +{ + "absolutePath": "L", + "exportedSymbols": + { + "L": + [ + 78 + ], + "free1": + [ + 65 + ], + "free2": + [ + 69 + ] + }, + "id": 79, + "nodeType": "SourceUnit", + "nodes": + [ + { + "body": + { + "id": 64, + "nodeType": "Block", + "src": "17:2:1", + "statements": [] + }, + "id": 65, + "implemented": true, + "kind": "freeFunction", + "modifiers": [], + "name": "free1", + "nameLocation": "9:5:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 62, + "nodeType": "ParameterList", + "parameters": [], + "src": "14:2:1" + }, + "returnParameters": + { + "id": 63, + "nodeType": "ParameterList", + "parameters": [], + "src": "17:0:1" + }, + "scope": 79, + "src": "0:19:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 68, + "nodeType": "Block", + "src": "37:2:1", + "statements": [] + }, + "id": 69, + "implemented": true, + "kind": "freeFunction", + "modifiers": [], + "name": "free2", + "nameLocation": "29:5:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 66, + "nodeType": "ParameterList", + "parameters": [], + "src": "34:2:1" + }, + "returnParameters": + { + "id": 67, + "nodeType": "ParameterList", + "parameters": [], + "src": "37:0:1" + }, + "scope": 79, + "src": "20:19:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "L", + "contractDependencies": [], + "contractKind": "library", + "fullyImplemented": true, + "id": 78, + "linearizedBaseContracts": + [ + 78 + ], + "name": "L", + "nameLocation": "48:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 72, + "nodeType": "Block", + "src": "78:2:1", + "statements": [] + }, + "id": 73, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "g", + "nameLocation": "65:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 70, + "nodeType": "ParameterList", + "parameters": [], + "src": "66:2:1" + }, + "returnParameters": + { + "id": 71, + "nodeType": "ParameterList", + "parameters": [], + "src": "78:0:1" + }, + "scope": 78, + "src": "56:24:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 76, + "nodeType": "Block", + "src": "107:2:1", + "statements": [] + }, + "id": 77, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "h", + "nameLocation": "94:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 74, + "nodeType": "ParameterList", + "parameters": [], + "src": "95:2:1" + }, + "returnParameters": + { + "id": 75, + "nodeType": "ParameterList", + "parameters": [], + "src": "107:0:1" + }, + "scope": 78, + "src": "85:24:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 79, + "src": "40:71:1", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "0:112:1" +}, +{ + "absolutePath": "A", + "exportedSymbols": + { + "A": + [ + 22 + ], + "B": + [ + 37 + ], + "L": + [ + 78 + ], + "free1": + [ + 65 + ], + "free2": + [ + 69 + ] + }, + "id": 38, + "nodeType": "SourceUnit", + "nodes": + [ + { + "absolutePath": "L", + "file": "L", + "id": 1, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 38, + "sourceUnit": 79, + "src": "0:11:2", + "symbolAliases": [], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "A", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 22, + "internalFunctionIDs": + { + "69": 1, + "73": 2, + "77": 3 + }, + "linearizedBaseContracts": + [ + 22 + ], + "name": "A", + "nameLocation": "21:1:2", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 20, + "nodeType": "Block", + "src": "49:60:2", + "statements": + [ + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "expression": + { + "id": 4, + "name": "L", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 78, + "src": "60:1:2", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_L_$78_$", + "typeString": "type(library L)" + } + }, + "id": 6, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "62:1:2", + "memberName": "g", + "nodeType": "MemberAccess", + "referencedDeclaration": 73, + "src": "60:3:2", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 7, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "59:5:2", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 8, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "59:7:2", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 9, + "nodeType": "ExpressionStatement", + "src": "59:7:2" + }, + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "id": 10, + "name": "free2", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 69, + "src": "77:5:2", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 11, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "76:7:2", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 12, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "76:9:2", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 13, + "nodeType": "ExpressionStatement", + "src": "76:9:2" + }, + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "expression": + { + "id": 14, + "name": "L", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 78, + "src": "96:1:2", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_L_$78_$", + "typeString": "type(library L)" + } + }, + "id": 16, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "98:1:2", + "memberName": "h", + "nodeType": "MemberAccess", + "referencedDeclaration": 77, + "src": "96:3:2", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 17, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "95:5:2", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 18, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "95:7:2", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 19, + "nodeType": "ExpressionStatement", + "src": "95:7:2" + } + ] + }, + "functionSelector": "26121ff0", + "id": 21, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "38:1:2", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "39:2:2" + }, + "returnParameters": + { + "id": 3, + "nodeType": "ParameterList", + "parameters": [], + "src": "49:0:2" + }, + "scope": 22, + "src": "29:80:2", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 38, + "src": "12:99:2", + "usedErrors": [], + "usedEvents": [] + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "B", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 37, + "internalFunctionIDs": + { + "69": 1, + "77": 2 + }, + "linearizedBaseContracts": + [ + 37 + ], + "name": "B", + "nameLocation": "121:1:2", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 35, + "nodeType": "Block", + "src": "149:43:2", + "statements": + [ + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "expression": + { + "id": 25, + "name": "L", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 78, + "src": "160:1:2", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_L_$78_$", + "typeString": "type(library L)" + } + }, + "id": 27, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "162:1:2", + "memberName": "h", + "nodeType": "MemberAccess", + "referencedDeclaration": 77, + "src": "160:3:2", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 28, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "159:5:2", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 29, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "159:7:2", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 30, + "nodeType": "ExpressionStatement", + "src": "159:7:2" + }, + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "id": 31, + "name": "free2", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 69, + "src": "177:5:2", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 32, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "176:7:2", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 33, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "176:9:2", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 34, + "nodeType": "ExpressionStatement", + "src": "176:9:2" + } + ] + }, + "functionSelector": "26121ff0", + "id": 36, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "138:1:2", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 23, + "nodeType": "ParameterList", + "parameters": [], + "src": "139:2:2" + }, + "returnParameters": + { + "id": 24, + "nodeType": "ParameterList", + "parameters": [], + "src": "149:0:2" + }, + "scope": 37, + "src": "129:63:2", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 38, + "src": "112:82:2", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "0:195:2" +}, +{ + "absolutePath": "C", + "exportedSymbols": + { + "C": + [ + 60 + ], + "L": + [ + 78 + ], + "free1": + [ + 65 + ], + "free2": + [ + 69 + ] + }, + "id": 61, + "nodeType": "SourceUnit", + "nodes": + [ + { + "absolutePath": "L", + "file": "L", + "id": 39, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 61, + "sourceUnit": 79, + "src": "0:11:3", + "symbolAliases": [], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 60, + "internalFunctionIDs": + { + "69": 1, + "73": 2, + "77": 3 + }, + "linearizedBaseContracts": + [ + 60 + ], + "name": "C", + "nameLocation": "21:1:3", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 58, + "nodeType": "Block", + "src": "49:60:3", + "statements": + [ + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "expression": + { + "id": 42, + "name": "L", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 78, + "src": "60:1:3", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_L_$78_$", + "typeString": "type(library L)" + } + }, + "id": 44, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "62:1:3", + "memberName": "g", + "nodeType": "MemberAccess", + "referencedDeclaration": 73, + "src": "60:3:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 45, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "59:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 46, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "59:7:3", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 47, + "nodeType": "ExpressionStatement", + "src": "59:7:3" + }, + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "id": 48, + "name": "free2", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 69, + "src": "77:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 49, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "76:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 50, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "76:9:3", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 51, + "nodeType": "ExpressionStatement", + "src": "76:9:3" + }, + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "expression": + { + "id": 52, + "name": "L", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 78, + "src": "96:1:3", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_L_$78_$", + "typeString": "type(library L)" + } + }, + "id": 54, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "98:1:3", + "memberName": "h", + "nodeType": "MemberAccess", + "referencedDeclaration": 77, + "src": "96:3:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 55, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "95:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 56, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "95:7:3", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 57, + "nodeType": "ExpressionStatement", + "src": "95:7:3" + } + ] + }, + "functionSelector": "26121ff0", + "id": 59, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "38:1:3", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 40, + "nodeType": "ParameterList", + "parameters": [], + "src": "39:2:3" + }, + "returnParameters": + { + "id": 41, + "nodeType": "ParameterList", + "parameters": [], + "src": "49:0:3" + }, + "scope": 60, + "src": "29:80:3", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 61, + "src": "12:99:3", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "0:112:3" +} +] diff --git a/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.sol b/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.sol new file mode 100644 index 000000000000..6e0b28c82ac3 --- /dev/null +++ b/test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.sol @@ -0,0 +1,38 @@ +==== Source: L ==== + +function free1() {} +function free2() {} +library L { + function g() internal {} + function h() internal {} +} + +==== Source: A ==== + +import "L"; +contract A { + function f() public { + (L.g)(); + (free2)(); + (L.h)(); + } +} +contract B { + function f() public { + (L.h)(); + (free2)(); + } +} + +==== Source: C ==== + +import "L"; +contract C { + function f() public { + (L.g)(); + (free2)(); + (L.h)(); + } +} + +// ---- diff --git a/test/libsolidity/ASTJSON/ast_internal_function_id_export.json b/test/libsolidity/ASTJSON/ast_internal_function_id_export.json index 3e6e67bdde9c..d452f2d99fec 100644 --- a/test/libsolidity/ASTJSON/ast_internal_function_id_export.json +++ b/test/libsolidity/ASTJSON/ast_internal_function_id_export.json @@ -41,7 +41,6 @@ }, "id": 4, "implemented": true, - "internalFunctionID": 1, "kind": "freeFunction", "modifiers": [], "name": "free1", @@ -77,7 +76,6 @@ }, "id": 8, "implemented": true, - "internalFunctionID": 2, "kind": "freeFunction", "modifiers": [], "name": "free2", @@ -146,6 +144,13 @@ "contractKind": "library", "fullyImplemented": true, "id": 53, + "internalFunctionIDs": + { + "20": 3, + "24": 4, + "4": 1, + "8": 2 + }, "linearizedBaseContracts": [ 53 @@ -201,7 +206,6 @@ }, "id": 20, "implemented": true, - "internalFunctionID": 3, "kind": "function", "modifiers": [], "name": "inr1", @@ -237,7 +241,6 @@ }, "id": 24, "implemented": true, - "internalFunctionID": 4, "kind": "function", "modifiers": [], "name": "inr2", @@ -579,6 +582,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 128, + "internalFunctionIDs": + { + "20": 3, + "24": 4, + "4": 1, + "69": 5, + "73": 6, + "8": 2 + }, "linearizedBaseContracts": [ 128 @@ -706,7 +718,6 @@ }, "id": 69, "implemented": true, - "internalFunctionID": 5, "kind": "function", "modifiers": [], "name": "inr1", @@ -742,7 +753,6 @@ }, "id": 73, "implemented": true, - "internalFunctionID": 6, "kind": "function", "modifiers": [], "name": "inr2", @@ -1405,6 +1415,15 @@ "contractKind": "contract", "fullyImplemented": true, "id": 141, + "internalFunctionIDs": + { + "20": 3, + "24": 4, + "4": 1, + "69": 5, + "73": 6, + "8": 2 + }, "linearizedBaseContracts": [ 141,