From a0e62bbd3d45da338a5d68cbbe9a053f3fa082b2 Mon Sep 17 00:00:00 2001 From: "Rodrigo Q. Saramago" Date: Wed, 15 Mar 2023 14:38:03 +0100 Subject: [PATCH] Annotate function ID of functions that may be called via the internal dispatch. Co-authored-by: Daniel --- Changelog.md | 4 + libsolidity/ast/ASTAnnotations.h | 1 + libsolidity/ast/ASTJsonExporter.cpp | 4 + .../codegen/ir/IRGenerationContext.cpp | 14 - libsolidity/codegen/ir/IRGenerationContext.h | 10 - libsolidity/codegen/ir/IRGenerator.cpp | 3 +- .../codegen/ir/IRGeneratorForStatements.cpp | 2 +- libsolidity/interface/CompilerStack.cpp | 29 + libsolidity/interface/CompilerStack.h | 3 + .../ast_internal_function_id_export.json | 1540 +++++++++++++++++ .../ast_internal_function_id_export.sol | 48 + 11 files changed, 1631 insertions(+), 27 deletions(-) create mode 100644 test/libsolidity/ASTJSON/ast_internal_function_id_export.json create mode 100644 test/libsolidity/ASTJSON/ast_internal_function_id_export.sol diff --git a/Changelog.md b/Changelog.md index f51aaffb26af..ac0ff9b37154 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,10 @@ Compiler Features: 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. + + ### 0.8.19 (2023-02-22) Language Features: diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index b85eb3ad0a9d..d5087c429e2c 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -178,6 +178,7 @@ 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 e35d10821622..4dc2f86c5e3f 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -468,6 +468,10 @@ bool ASTJsonExporter::visit(FunctionDefinition const& _node) attributes.emplace_back("functionSelector", _node.externalIdentifierHex()); 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/IRGenerationContext.cpp b/libsolidity/codegen/ir/IRGenerationContext.cpp index cb1c371dc99f..9ff3a6afeaeb 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.cpp +++ b/libsolidity/codegen/ir/IRGenerationContext.cpp @@ -177,17 +177,3 @@ ABIFunctions IRGenerationContext::abiFunctions() { return ABIFunctions(m_evmVersion, m_revertStrings, m_functions); } - -uint64_t IRGenerationContext::internalFunctionID(FunctionDefinition const& _function, bool _requirePresent) -{ - auto [iterator, inserted] = m_functionIDs.try_emplace(_function.id(), m_functionIDs.size() + 1); - if (_requirePresent) - solAssert(!inserted, ""); - return iterator->second; -} - -void IRGenerationContext::copyFunctionIDsFrom(IRGenerationContext const& _other) -{ - solAssert(m_functionIDs.empty(), ""); - m_functionIDs = _other.m_functionIDs; -} diff --git a/libsolidity/codegen/ir/IRGenerationContext.h b/libsolidity/codegen/ir/IRGenerationContext.h index ea960bb70bca..14a70a8a6c09 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.h +++ b/libsolidity/codegen/ir/IRGenerationContext.h @@ -163,14 +163,6 @@ class IRGenerationContext bool memoryUnsafeInlineAssemblySeen() const { return m_memoryUnsafeInlineAssemblySeen; } void setMemoryUnsafeInlineAssemblySeen() { m_memoryUnsafeInlineAssemblySeen = true; } - /// @returns the runtime ID to be used for the function in the dispatch routine - /// and for internal function pointers. - /// @param _requirePresent if false, generates a new ID if not yet done. - uint64_t internalFunctionID(FunctionDefinition const& _function, bool _requirePresent); - /// Copies the internal function IDs from the @a _other. For use in transferring - /// function IDs from constructor code to deployed code. - void copyFunctionIDsFrom(IRGenerationContext const& _other); - std::map const& sourceIndices() const { return m_sourceIndices; } void markSourceUsed(std::string const& _name) { m_usedSourceNames.insert(_name); } std::set const& usedSourceNames() const { return m_usedSourceNames; } @@ -219,8 +211,6 @@ class IRGenerationContext /// the code contains a call via a pointer even though a specific function is never assigned to it. /// It will fail at runtime but the code must still compile. InternalDispatchMap m_internalDispatchMap; - /// Map used by @a internalFunctionID. - std::map m_functionIDs; std::set m_subObjects; diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 371301804193..cf11a8a02b1b 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(m_context.internalFunctionID(*function, true))}, + {"funID", to_string(*function->annotation().internalFunctionID)}, {"name", IRNames::function(*function)} }); } @@ -1117,7 +1117,6 @@ void IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionCon m_context.debugInfoSelection(), m_context.soliditySourceProvider() ); - newContext.copyFunctionIDsFrom(m_context); m_context = std::move(newContext); m_context.setMostDerivedContract(_contract); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index a9eb0bf15270..2263e11496bd 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(m_context.internalFunctionID(_referencedFunction, false)) << + to_string(*_referencedFunction.annotation().internalFunctionID) << "\n"; m_context.addToInternalDispatch(_referencedFunction); } diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 14fa3c5289bc..13eaae08a6c3 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -526,6 +526,7 @@ bool CompilerStack::analyze() if (noErrors) { createAndAssignCallGraphs(); + annotateInternalFunctionIDs(); findAndReportCyclicContractDependencies(); } @@ -1245,6 +1246,34 @@ void CompilerStack::storeContractDefinitions() } } +void CompilerStack::annotateInternalFunctionIDs() +{ + uint64_t internalFunctionID = 1; + for (Source const* source: m_sourceOrder) + { + if (!source->ast) + continue; + + for (ContractDefinition const* contract: ASTNode::filteredNodes(source->ast->nodes())) + { + 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++; + 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()); + } + } +} + namespace { bool onlySafeExperimentalFeaturesActivated(set const& features) diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 099c1f003045..cd742140587d 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -415,6 +415,9 @@ class CompilerStack: public langutil::CharStreamProvider /// Store the contract definitions in m_contracts. void storeContractDefinitions(); + /// Annotate internal dispatch function Ids + void annotateInternalFunctionIDs(); + /// @returns true if the source is requested to be compiled. bool isRequestedSource(std::string const& _sourceName) const; diff --git a/test/libsolidity/ASTJSON/ast_internal_function_id_export.json b/test/libsolidity/ASTJSON/ast_internal_function_id_export.json new file mode 100644 index 000000000000..02da00d6ddb9 --- /dev/null +++ b/test/libsolidity/ASTJSON/ast_internal_function_id_export.json @@ -0,0 +1,1540 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 128 + ], + "D": + [ + 141 + ], + "L": + [ + 53 + ], + "free1": + [ + 4 + ], + "free2": + [ + 8 + ], + "free3": + [ + 12 + ] + }, + "id": 142, + "nodeType": "SourceUnit", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "17:2:1", + "statements": [] + }, + "id": 4, + "implemented": true, + "internalFunctionID": 1, + "kind": "freeFunction", + "modifiers": [], + "name": "free1", + "nameLocation": "9:5:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "14:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "17:0:1" + }, + "scope": 142, + "src": "0:19:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 7, + "nodeType": "Block", + "src": "37:2:1", + "statements": [] + }, + "id": 8, + "implemented": true, + "internalFunctionID": 2, + "kind": "freeFunction", + "modifiers": [], + "name": "free2", + "nameLocation": "29:5:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 5, + "nodeType": "ParameterList", + "parameters": [], + "src": "34:2:1" + }, + "returnParameters": + { + "id": 6, + "nodeType": "ParameterList", + "parameters": [], + "src": "37:0:1" + }, + "scope": 142, + "src": "20:19:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 11, + "nodeType": "Block", + "src": "57:2:1", + "statements": [] + }, + "id": 12, + "implemented": true, + "kind": "freeFunction", + "modifiers": [], + "name": "free3", + "nameLocation": "49:5:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 9, + "nodeType": "ParameterList", + "parameters": [], + "src": "54:2:1" + }, + "returnParameters": + { + "id": 10, + "nodeType": "ParameterList", + "parameters": [], + "src": "57:0:1" + }, + "scope": 142, + "src": "40:19:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "L", + "contractDependencies": [], + "contractKind": "library", + "fullyImplemented": true, + "id": 53, + "linearizedBaseContracts": + [ + 53 + ], + "name": "L", + "nameLocation": "68:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 15, + "nodeType": "Block", + "src": "100:2:1", + "statements": [] + }, + "functionSelector": "cf9f23b5", + "id": 16, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "ext", + "nameLocation": "85:3:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 13, + "nodeType": "ParameterList", + "parameters": [], + "src": "88:2:1" + }, + "returnParameters": + { + "id": 14, + "nodeType": "ParameterList", + "parameters": [], + "src": "100:0:1" + }, + "scope": 53, + "src": "76:26:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "body": + { + "id": 19, + "nodeType": "Block", + "src": "132:2:1", + "statements": [] + }, + "id": 20, + "implemented": true, + "internalFunctionID": 3, + "kind": "function", + "modifiers": [], + "name": "inr1", + "nameLocation": "116:4:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 17, + "nodeType": "ParameterList", + "parameters": [], + "src": "120:2:1" + }, + "returnParameters": + { + "id": 18, + "nodeType": "ParameterList", + "parameters": [], + "src": "132:0:1" + }, + "scope": 53, + "src": "107:27:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 23, + "nodeType": "Block", + "src": "164:2:1", + "statements": [] + }, + "id": 24, + "implemented": true, + "internalFunctionID": 4, + "kind": "function", + "modifiers": [], + "name": "inr2", + "nameLocation": "148:4:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 21, + "nodeType": "ParameterList", + "parameters": [], + "src": "152:2:1" + }, + "returnParameters": + { + "id": 22, + "nodeType": "ParameterList", + "parameters": [], + "src": "164:0:1" + }, + "scope": 53, + "src": "139:27:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 27, + "nodeType": "Block", + "src": "196:2:1", + "statements": [] + }, + "id": 28, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "inr3", + "nameLocation": "180:4:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 25, + "nodeType": "ParameterList", + "parameters": [], + "src": "184:2:1" + }, + "returnParameters": + { + "id": 26, + "nodeType": "ParameterList", + "parameters": [], + "src": "196:0:1" + }, + "scope": 53, + "src": "171:27:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 39, + "nodeType": "Block", + "src": "228:51:1", + "statements": + [ + { + "expression": + { + "id": 31, + "name": "free1", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4, + "src": "238:5:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 32, + "nodeType": "ExpressionStatement", + "src": "238:5:1" + }, + { + "expression": + { + "id": 33, + "name": "inr1", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20, + "src": "253:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 34, + "nodeType": "ExpressionStatement", + "src": "253:4:1" + }, + { + "expression": + { + "expression": + { + "id": 35, + "name": "L", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 53, + "src": "267:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_L_$53_$", + "typeString": "type(library L)" + } + }, + "id": 37, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "269:3:1", + "memberName": "ext", + "nodeType": "MemberAccess", + "referencedDeclaration": 16, + "src": "267:5:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_delegatecall_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 38, + "nodeType": "ExpressionStatement", + "src": "267:5:1" + } + ] + }, + "functionSelector": "71907f17", + "id": 40, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "access", + "nameLocation": "212:6:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 29, + "nodeType": "ParameterList", + "parameters": [], + "src": "218:2:1" + }, + "returnParameters": + { + "id": 30, + "nodeType": "ParameterList", + "parameters": [], + "src": "228:0:1" + }, + "scope": 53, + "src": "203:76:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "body": + { + "id": 51, + "nodeType": "Block", + "src": "313:44:1", + "statements": + [ + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "id": 43, + "name": "free2", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8, + "src": "324:5:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 44, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "323:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 45, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "323:9:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 46, + "nodeType": "ExpressionStatement", + "src": "323:9:1" + }, + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "id": 47, + "name": "inr2", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 24, + "src": "343:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 48, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "342:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 49, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "342:8:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50, + "nodeType": "ExpressionStatement", + "src": "342:8:1" + } + ] + }, + "functionSelector": "4228dae0", + "id": 52, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "expression", + "nameLocation": "293:10:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 41, + "nodeType": "ParameterList", + "parameters": [], + "src": "303:2:1" + }, + "returnParameters": + { + "id": 42, + "nodeType": "ParameterList", + "parameters": [], + "src": "313:0:1" + }, + "scope": 53, + "src": "284:73:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 142, + "src": "60:299:1", + "usedErrors": [] + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 128, + "linearizedBaseContracts": + [ + 128 + ], + "name": "C", + "nameLocation": "369:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 56, + "nodeType": "Block", + "src": "402:2:1", + "statements": [] + }, + "functionSelector": "05b07a6b", + "id": 57, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "ext1", + "nameLocation": "386:4:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 54, + "nodeType": "ParameterList", + "parameters": [], + "src": "390:2:1" + }, + "returnParameters": + { + "id": 55, + "nodeType": "ParameterList", + "parameters": [], + "src": "402:0:1" + }, + "scope": 128, + "src": "377:27:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "body": + { + "id": 60, + "nodeType": "Block", + "src": "434:2:1", + "statements": [] + }, + "functionSelector": "5aa6e183", + "id": 61, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "ext2", + "nameLocation": "418:4:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 58, + "nodeType": "ParameterList", + "parameters": [], + "src": "422:2:1" + }, + "returnParameters": + { + "id": 59, + "nodeType": "ParameterList", + "parameters": [], + "src": "434:0:1" + }, + "scope": 128, + "src": "409:27:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "body": + { + "id": 64, + "nodeType": "Block", + "src": "466:2:1", + "statements": [] + }, + "functionSelector": "0a77b8ef", + "id": 65, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "ext3", + "nameLocation": "450:4:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 62, + "nodeType": "ParameterList", + "parameters": [], + "src": "454:2:1" + }, + "returnParameters": + { + "id": 63, + "nodeType": "ParameterList", + "parameters": [], + "src": "466:0:1" + }, + "scope": 128, + "src": "441:27:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "body": + { + "id": 68, + "nodeType": "Block", + "src": "498:2:1", + "statements": [] + }, + "id": 69, + "implemented": true, + "internalFunctionID": 5, + "kind": "function", + "modifiers": [], + "name": "inr1", + "nameLocation": "482:4:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 66, + "nodeType": "ParameterList", + "parameters": [], + "src": "486:2:1" + }, + "returnParameters": + { + "id": 67, + "nodeType": "ParameterList", + "parameters": [], + "src": "498:0:1" + }, + "scope": 128, + "src": "473:27:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 72, + "nodeType": "Block", + "src": "530:2:1", + "statements": [] + }, + "id": 73, + "implemented": true, + "internalFunctionID": 6, + "kind": "function", + "modifiers": [], + "name": "inr2", + "nameLocation": "514:4:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 70, + "nodeType": "ParameterList", + "parameters": [], + "src": "518:2:1" + }, + "returnParameters": + { + "id": 71, + "nodeType": "ParameterList", + "parameters": [], + "src": "530:0:1" + }, + "scope": 128, + "src": "505:27:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 76, + "nodeType": "Block", + "src": "562:2:1", + "statements": [] + }, + "id": 77, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "inr3", + "nameLocation": "546:4:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 74, + "nodeType": "ParameterList", + "parameters": [], + "src": "550:2:1" + }, + "returnParameters": + { + "id": 75, + "nodeType": "ParameterList", + "parameters": [], + "src": "562:0:1" + }, + "scope": 128, + "src": "537:27:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 96, + "nodeType": "Block", + "src": "594:86:1", + "statements": + [ + { + "expression": + { + "expression": + { + "id": 80, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "604:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_C_$128", + "typeString": "contract C" + } + }, + "id": 82, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "609:4:1", + "memberName": "ext1", + "nodeType": "MemberAccess", + "referencedDeclaration": 57, + "src": "604:9:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_nonpayable$__$returns$__$", + "typeString": "function () external" + } + }, + "id": 83, + "nodeType": "ExpressionStatement", + "src": "604:9:1" + }, + { + "expression": + { + "id": 84, + "name": "inr1", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 69, + "src": "623:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 85, + "nodeType": "ExpressionStatement", + "src": "623:4:1" + }, + { + "expression": + { + "id": 86, + "name": "free1", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4, + "src": "637:5:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 87, + "nodeType": "ExpressionStatement", + "src": "637:5:1" + }, + { + "expression": + { + "expression": + { + "id": 88, + "name": "L", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 53, + "src": "652:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_L_$53_$", + "typeString": "type(library L)" + } + }, + "id": 90, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "654:4:1", + "memberName": "inr1", + "nodeType": "MemberAccess", + "referencedDeclaration": 20, + "src": "652:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 91, + "nodeType": "ExpressionStatement", + "src": "652:6:1" + }, + { + "expression": + { + "expression": + { + "id": 92, + "name": "L", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 53, + "src": "668:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_L_$53_$", + "typeString": "type(library L)" + } + }, + "id": 94, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "670:3:1", + "memberName": "ext", + "nodeType": "MemberAccess", + "referencedDeclaration": 16, + "src": "668:5:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_delegatecall_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 95, + "nodeType": "ExpressionStatement", + "src": "668:5:1" + } + ] + }, + "functionSelector": "71907f17", + "id": 97, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "access", + "nameLocation": "578:6:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 78, + "nodeType": "ParameterList", + "parameters": [], + "src": "584:2:1" + }, + "returnParameters": + { + "id": 79, + "nodeType": "ParameterList", + "parameters": [], + "src": "594:0:1" + }, + "scope": 128, + "src": "569:111:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "body": + { + "id": 126, + "nodeType": "Block", + "src": "714:106:1", + "statements": + [ + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "expression": + { + "id": 100, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "725:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_C_$128", + "typeString": "contract C" + } + }, + "id": 102, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "730:4:1", + "memberName": "ext2", + "nodeType": "MemberAccess", + "referencedDeclaration": 61, + "src": "725:9:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_nonpayable$__$returns$__$", + "typeString": "function () external" + } + } + ], + "id": 103, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "724:11:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_nonpayable$__$returns$__$", + "typeString": "function () external" + } + }, + "id": 104, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "724:13:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 105, + "nodeType": "ExpressionStatement", + "src": "724:13:1" + }, + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "id": 106, + "name": "inr2", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 73, + "src": "748:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 107, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "747:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 108, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "747:8:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 109, + "nodeType": "ExpressionStatement", + "src": "747:8:1" + }, + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "id": 110, + "name": "free2", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8, + "src": "766:5:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 111, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "765:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 112, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "765:9:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 113, + "nodeType": "ExpressionStatement", + "src": "765:9:1" + }, + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "expression": + { + "id": 114, + "name": "L", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 53, + "src": "785:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_L_$53_$", + "typeString": "type(library L)" + } + }, + "id": 116, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "787:4:1", + "memberName": "inr2", + "nodeType": "MemberAccess", + "referencedDeclaration": 24, + "src": "785:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 117, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "784:8:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 118, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "784:10:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 119, + "nodeType": "ExpressionStatement", + "src": "784:10:1" + }, + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "components": + [ + { + "expression": + { + "id": 120, + "name": "L", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 53, + "src": "805:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_L_$53_$", + "typeString": "type(library L)" + } + }, + "id": 122, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "807:3:1", + "memberName": "ext", + "nodeType": "MemberAccess", + "referencedDeclaration": 16, + "src": "805:5:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_delegatecall_nonpayable$__$returns$__$", + "typeString": "function ()" + } + } + ], + "id": 123, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "804:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_delegatecall_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 124, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "804:9:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 125, + "nodeType": "ExpressionStatement", + "src": "804:9:1" + } + ] + }, + "functionSelector": "4228dae0", + "id": 127, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "expression", + "nameLocation": "694:10:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 98, + "nodeType": "ParameterList", + "parameters": [], + "src": "704:2:1" + }, + "returnParameters": + { + "id": 99, + "nodeType": "ParameterList", + "parameters": [], + "src": "714:0:1" + }, + "scope": 128, + "src": "685:135:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 142, + "src": "360:462:1", + "usedErrors": [] + }, + { + "abstract": false, + "baseContracts": + [ + { + "baseName": + { + "id": 129, + "name": "C", + "nameLocations": + [ + "837:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 128, + "src": "837:1:1" + }, + "id": 130, + "nodeType": "InheritanceSpecifier", + "src": "837:1:1" + } + ], + "canonicalName": "D", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 141, + "linearizedBaseContracts": + [ + 141, + 128 + ], + "name": "D", + "nameLocation": "832:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 139, + "nodeType": "Block", + "src": "859:47:1", + "statements": + [ + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "id": 133, + "name": "access", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 97, + "src": "869:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 134, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "869:8:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 135, + "nodeType": "ExpressionStatement", + "src": "869:8:1" + }, + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "id": 136, + "name": "expression", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 127, + "src": "887:10:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 137, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "887:12:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 138, + "nodeType": "ExpressionStatement", + "src": "887:12:1" + } + ] + }, + "id": 140, + "implemented": true, + "kind": "constructor", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 131, + "nodeType": "ParameterList", + "parameters": [], + "src": "856:2:1" + }, + "returnParameters": + { + "id": 132, + "nodeType": "ParameterList", + "parameters": [], + "src": "859:0:1" + }, + "scope": 141, + "src": "845:61:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 142, + "src": "823:85:1", + "usedErrors": [] + } + ], + "src": "0:909:1" +} diff --git a/test/libsolidity/ASTJSON/ast_internal_function_id_export.sol b/test/libsolidity/ASTJSON/ast_internal_function_id_export.sol new file mode 100644 index 000000000000..100897b71f03 --- /dev/null +++ b/test/libsolidity/ASTJSON/ast_internal_function_id_export.sol @@ -0,0 +1,48 @@ +function free1() {} +function free2() {} +function free3() {} +library L { + function ext() external {} + function inr1() internal {} + function inr2() internal {} + function inr3() internal {} + function access() public { + free1; + inr1; + L.ext; + } + function expression() public { + (free2)(); + (inr2)(); + } +} +contract C { + function ext1() external {} + function ext2() external {} + function ext3() external {} + function inr1() internal {} + function inr2() internal {} + function inr3() internal {} + function access() public { + this.ext1; + inr1; + free1; + L.inr1; + L.ext; + } + function expression() public { + (this.ext2)(); + (inr2)(); + (free2)(); + (L.inr2)(); + (L.ext)(); + } +} +contract D is C { + constructor() { + access(); + expression(); + } +} + +// ----