From e590a99f399e0be33dfba0ab63065d7f17e1e870 Mon Sep 17 00:00:00 2001 From: Mathias Baumann Date: Thu, 29 Oct 2020 15:07:09 +0100 Subject: [PATCH] Detect circular references for library and free functions --- Changelog.md | 1 + libsolidity/analysis/NameAndTypeResolver.cpp | 1 - libsolidity/analysis/TypeChecker.cpp | 49 -- libsolidity/analysis/TypeChecker.h | 5 - libsolidity/ast/AST.h | 19 +- libsolidity/ast/ASTAnnotations.h | 7 +- libsolidity/ast/ASTForward.h | 19 + libsolidity/ast/ASTJsonConverter.cpp | 4 +- libsolidity/ast/CallGraph.h | 2 +- libsolidity/interface/CompilerStack.cpp | 120 ++- libsolidity/interface/CompilerStack.h | 4 + .../ASTJSON/base_constructor_call.json | 5 +- .../ASTJSON/contract_dep_order.json | 26 +- .../ASTJSON/inheritance_specifier.json | 5 +- test/libsolidity/ASTJSON/override.json | 133 ++- test/libsolidity/ASTJSON/override.sol | 10 +- .../ASTJSON/override_parseOnly.json | 106 ++- .../ASTJSON/two_base_functions.json | 6 +- .../circular_reference_complex.sol | 7 + .../circular_reference_complex1.sol | 6 + .../circular_reference_free_function.sol | 11 + ...circular_reference_function_parameters.sol | 3 + .../circular_reference_internal_function.sol | 11 + .../circular_reference_internal_functions.sol | 3 + .../circular_reference_libraries.sol | 3 + .../circular_reference_mention_only.sol | 9 + .../circular_reference_new_in_ctor.sol | 5 + ...rcular_reference_report_first_in_cycle.sol | 13 + .../circular_reference_type_mention_only.sol | 9 + .../cyclic_dep_exhaustion.sol | 773 ++++++++++++++++++ .../library_function_circular_reference.sol | 18 + .../circular_reference1functions_first.sol | 18 + .../circular_referencecontracts_first.sol | 18 + .../syntaxTests/metaTypes/codeAccessBase.sol | 18 +- .../metaTypes/codeAccessCyclic.sol | 3 +- ..._creating_contract_within_the_contract.sol | 2 +- .../236_cyclic_binary_dependency.sol | 4 +- 37 files changed, 1168 insertions(+), 288 deletions(-) create mode 100644 test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_complex.sol create mode 100644 test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_complex1.sol create mode 100644 test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_free_function.sol create mode 100644 test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_function_parameters.sol create mode 100644 test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_function.sol create mode 100644 test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_functions.sol create mode 100644 test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_libraries.sol create mode 100644 test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_mention_only.sol create mode 100644 test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_new_in_ctor.sol create mode 100644 test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_report_first_in_cycle.sol create mode 100644 test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_type_mention_only.sol create mode 100644 test/libsolidity/syntaxTests/bytecodeReferences/cyclic_dep_exhaustion.sol create mode 100644 test/libsolidity/syntaxTests/bytecodeReferences/library_function_circular_reference.sol create mode 100644 test/libsolidity/syntaxTests/freeFunctions/circular_reference1functions_first.sol create mode 100644 test/libsolidity/syntaxTests/freeFunctions/circular_referencecontracts_first.sol diff --git a/Changelog.md b/Changelog.md index a3ce22a8e..3aabb8b99 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Language Features: * Possibility to use ``bytes.concat`` with variable number of ``bytes`` and ``bytesNN`` arguments which behaves as a restricted version of `abi.encodePacked` with a more descriptive name. Compiler Features: + * Analysis: Properly detect circular references to the bytecode of other contracts across all function calls. * Commandline Interface: Model checker option ``--model-checker-targets`` also accepts ``outOfBounds``. * Low-Level Inliner: Inline ordinary jumps to small blocks and jumps to small blocks that terminate. * SMTChecker: Report local variables in CHC counterexamples. diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 03bf34f92..5645111f1 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -389,7 +389,6 @@ void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract) if (result.empty()) m_errorReporter.fatalTypeError(5005_error, _contract.location(), "Linearization of inheritance graph impossible"); _contract.annotation().linearizedBaseContracts = result; - _contract.annotation().contractDependencies.insert(result.begin() + 1, result.end()); } template diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index f5aecd252..d13c2eaae 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -2662,24 +2662,6 @@ void TypeChecker::endVisit(NewExpression const& _newExpression) if (contract->abstract()) m_errorReporter.typeError(4614_error, _newExpression.location(), "Cannot instantiate an abstract contract."); - if (m_currentContract) - { - // TODO this is not properly detecting creation-cycles if they go through - // internal library functions or free functions. It will be caught at - // code generation time, but it would of course be better to catch it here. - m_currentContract->annotation().contractDependencies.insert(contract); - solAssert( - !contract->annotation().linearizedBaseContracts.empty(), - "Linearized base contracts not yet available." - ); - if (contractDependenciesAreCyclic(*m_currentContract)) - m_errorReporter.typeError( - 4579_error, - _newExpression.location(), - "Circular reference for contract creation (cannot create instance of derived or same contract)." - ); - } - _newExpression.annotation().type = FunctionType::newExpressionType(*contract); _newExpression.annotation().isPure = false; } @@ -2953,21 +2935,6 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) _memberAccess.location(), "\"runtimeCode\" is not available for contracts containing immutable variables." ); - if (m_currentContract) - { - // TODO in the same way as with ``new``, - // this is not properly detecting creation-cycles if they go through - // internal library functions or free functions. It will be caught at - // code generation time, but it would of course be better to catch it here. - - m_currentContract->annotation().contractDependencies.insert(&accessedContractType.contractDefinition()); - if (contractDependenciesAreCyclic(*m_currentContract)) - m_errorReporter.typeError( - 4224_error, - _memberAccess.location(), - "Circular reference for contract code access." - ); - } } else if (magicType->kind() == MagicType::Kind::MetaType && memberName == "name") annotation.isPure = true; @@ -3455,22 +3422,6 @@ void TypeChecker::checkErrorAndEventParameters(CallableDeclaration const& _calla } } -bool TypeChecker::contractDependenciesAreCyclic( - ContractDefinition const& _contract, - std::set const& _seenContracts -) const -{ - // Naive depth-first search that remembers nodes already seen. - if (_seenContracts.count(&_contract)) - return true; - set seen(_seenContracts); - seen.insert(&_contract); - for (auto const* c: _contract.annotation().contractDependencies) - if (contractDependenciesAreCyclic(*c, seen)) - return true; - return false; -} - Declaration const& TypeChecker::dereference(Identifier const& _identifier) const { solAssert(!!_identifier.annotation().referencedDeclaration, "Declaration not stored."); diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index a9604bdec..e3714ddfc 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -157,11 +157,6 @@ private: void checkErrorAndEventParameters(CallableDeclaration const& _callable); - bool contractDependenciesAreCyclic( - ContractDefinition const& _contract, - std::set const& _seenContracts = std::set() - ) const; - /// @returns the referenced declaration and throws on error. Declaration const& dereference(Identifier const& _identifier) const; /// @returns the referenced declaration and throws on error. diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 4438620c7..c0d52c644 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -65,24 +65,7 @@ class ASTConstVisitor; class ASTNode: private boost::noncopyable { public: - struct CompareByID - { - using is_transparent = void; - - bool operator()(ASTNode const* _lhs, ASTNode const* _rhs) const - { - return _lhs->id() < _rhs->id(); - } - bool operator()(ASTNode const* _lhs, int64_t _rhs) const - { - return _lhs->id() < _rhs; - } - bool operator()(int64_t _lhs, ASTNode const* _rhs) const - { - return _lhs < _rhs->id(); - } - }; - + using CompareByID = frontend::ASTCompareByID; using SourceLocation = langutil::SourceLocation; explicit ASTNode(int64_t _id, SourceLocation _location); diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index c4212e201..9c08a374f 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -158,9 +158,6 @@ struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, StructurallyDocu /// List of all (direct and indirect) base contracts in order from derived to /// base, including the contract itself. std::vector linearizedBaseContracts; - /// List of contracts this contract creates, i.e. which need to be compiled first. - /// Also includes all contracts from @a linearizedBaseContracts. - std::set contractDependencies; /// Mapping containing the nodes that define the arguments for base constructors. /// These can either be inheritance specifiers or modifier invocations. std::map baseConstructorArguments; @@ -168,6 +165,10 @@ struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, StructurallyDocu SetOnce> creationCallGraph; /// A graph with edges representing calls between functions that may happen in a deployed contract. SetOnce> deployedCallGraph; + + /// 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; }; struct CallableDeclarationAnnotation: DeclarationAnnotation diff --git a/libsolidity/ast/ASTForward.h b/libsolidity/ast/ASTForward.h index d413c9e71..5b73eb3a3 100644 --- a/libsolidity/ast/ASTForward.h +++ b/libsolidity/ast/ASTForward.h @@ -100,6 +100,25 @@ class StructuredDocumentation; class VariableScope; +template +struct ASTCompareByID +{ + using is_transparent = void; + + bool operator()(T const* _lhs, T const* _rhs) const + { + return _lhs->id() < _rhs->id(); + } + bool operator()(T const* _lhs, int64_t _rhs) const + { + return _lhs->id() < _rhs; + } + bool operator()(int64_t _lhs, T const* _rhs) const + { + return _lhs < _rhs->id(); + } +}; + // Used as pointers to AST nodes, to be replaced by more clever pointers, e.g. pointers which do // not do reference counting but point to a special memory area that is completely released // explicitly. diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index ae8d57baf..b3aa47b00 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -41,7 +41,9 @@ #include #include #include +#include +using namespace ranges; using namespace std; using namespace solidity::langutil; @@ -269,7 +271,7 @@ bool ASTJsonConverter::visit(ContractDefinition const& _node) make_pair("contractKind", contractKind(_node.contractKind())), make_pair("abstract", _node.abstract()), make_pair("baseContracts", toJson(_node.baseContracts())), - make_pair("contractDependencies", getContainerIds(_node.annotation().contractDependencies, true)), + make_pair("contractDependencies", getContainerIds(_node.annotation().contractDependencies | views::keys)), make_pair("nodes", toJson(_node.subNodes())), make_pair("scope", idOrNull(_node.scope())) }; diff --git a/libsolidity/ast/CallGraph.h b/libsolidity/ast/CallGraph.h index f746d02e8..c4b4e957a 100644 --- a/libsolidity/ast/CallGraph.h +++ b/libsolidity/ast/CallGraph.h @@ -63,7 +63,7 @@ struct CallGraph /// Contracts that need to be compiled before this one can be compiled. /// The value is the ast node that created the dependency. - std::map bytecodeDependency; + std::map> bytecodeDependency; /// Events that may get emitted by functions present in the graph. std::set emittedEvents; diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 19d6ec7e3..5cdcface2 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -71,11 +71,15 @@ #include #include #include +#include #include -#include #include +#include +#include + +#include using namespace std; using namespace solidity; @@ -104,6 +108,94 @@ CompilerStack::~CompilerStack() TypeProvider::reset(); } +void CompilerStack::createAndAssignCallGraphs() +{ + for (Source const* source: m_sourceOrder) + { + if (!source->ast) + continue; + + for (ContractDefinition const* contract: ASTNode::filteredNodes(source->ast->nodes())) + { + ContractDefinitionAnnotation& annotation = + m_contracts.at(contract->fullyQualifiedName()).contract->annotation(); + + annotation.creationCallGraph = make_unique( + FunctionCallGraphBuilder::buildCreationGraph(*contract) + ); + annotation.deployedCallGraph = make_unique( + FunctionCallGraphBuilder::buildDeployedGraph( + *contract, + **annotation.creationCallGraph + ) + ); + + solAssert(annotation.contractDependencies.empty(), "contractDependencies expected to be empty?!"); + + annotation.contractDependencies = annotation.creationCallGraph->get()->bytecodeDependency; + + for (auto const& [dependencyContract, referencee]: annotation.deployedCallGraph->get()->bytecodeDependency) + annotation.contractDependencies.emplace(dependencyContract, referencee); + } + } +} + +void CompilerStack::findAndReportCyclicContractDependencies() +{ + // Cycles we found, used to avoid duplicate reports for the same reference + set foundCycles; + + for (Source const* source: m_sourceOrder) + { + if (!source->ast) + continue; + + for (ContractDefinition const* contractDefinition: ASTNode::filteredNodes(source->ast->nodes())) + { + util::CycleDetector cycleDetector{[&]( + ContractDefinition const& _contract, + util::CycleDetector& _cycleDetector, + size_t _depth + ) + { + // No specific reason for exactly that number, just a limit we're unlikely to hit. + if (_depth >= 256) + m_errorReporter.fatalTypeError( + 7864_error, + _contract.location(), + "Contract dependencies exhausting cyclic dependency validator" + ); + + for (auto& [dependencyContract, referencee]: _contract.annotation().contractDependencies) + if (_cycleDetector.run(*dependencyContract)) + return; + }}; + + ContractDefinition const* cycle = cycleDetector.run(*contractDefinition); + + if (!cycle) + continue; + + ASTNode const* referencee = contractDefinition->annotation().contractDependencies.at(cycle); + + if (foundCycles.find(referencee) != foundCycles.end()) + continue; + + SecondarySourceLocation secondaryLocation{}; + secondaryLocation.append("Referenced contract is here:"s, cycle->location()); + + m_errorReporter.typeError( + 7813_error, + referencee->location(), + secondaryLocation, + "Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\"." + ); + + foundCycles.emplace(referencee); + } + } +} + std::optional CompilerStack::parseRemapping(string const& _remapping) { auto eq = find(_remapping.begin(), _remapping.end(), '='); @@ -400,27 +492,11 @@ bool CompilerStack::analyze() if (source->ast && !typeChecker.checkTypeRequirements(*source->ast)) noErrors = false; + // Create & assign callgraphs and check for contract dependency cycles if (noErrors) { - for (Source const* source: m_sourceOrder) - if (source->ast) - for (ASTPointer const& node: source->ast->nodes()) - if (auto const* contractDefinition = dynamic_cast(node.get())) - { - Contract& contractState = m_contracts.at(contractDefinition->fullyQualifiedName()); - - contractState.contract->annotation().creationCallGraph = make_unique( - FunctionCallGraphBuilder::buildCreationGraph( - *contractDefinition - ) - ); - contractState.contract->annotation().deployedCallGraph = make_unique( - FunctionCallGraphBuilder::buildDeployedGraph( - *contractDefinition, - **contractState.contract->annotation().creationCallGraph - ) - ); - } + createAndAssignCallGraphs(); + findAndReportCyclicContractDependencies(); } if (noErrors) @@ -1206,7 +1282,7 @@ void CompilerStack::compileContract( if (_otherCompilers.count(&_contract)) return; - for (auto const* dependency: _contract.annotation().contractDependencies) + for (auto const& [dependency, referencee]: _contract.annotation().contractDependencies) compileContract(*dependency, _otherCompilers); if (!_contract.canBeDeployed()) @@ -1292,7 +1368,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract) ); string dependenciesSource; - for (auto const* dependency: _contract.annotation().contractDependencies) + for (auto const& [dependency, referencee]: _contract.annotation().contractDependencies) generateIR(*dependency); if (!_contract.canBeDeployed()) diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index a7861d221..d2052bd84 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -390,6 +390,9 @@ private: mutable std::optional runtimeSourceMapping; }; + void createAndAssignCallGraphs(); + void findAndReportCyclicContractDependencies(); + /// Loads the missing sources from @a _ast (named @a _path) using the callback /// @a m_readFile and stores the absolute paths of all imports in the AST annotations. /// @returns the newly loaded sources. @@ -495,6 +498,7 @@ private: std::shared_ptr m_globalContext; std::vector m_sourceOrder; std::map m_contracts; + langutil::ErrorList m_errorList; langutil::ErrorReporter m_errorReporter; bool m_metadataLiteralSources = false; diff --git a/test/libsolidity/ASTJSON/base_constructor_call.json b/test/libsolidity/ASTJSON/base_constructor_call.json index b67fa4e3e..a1cf5c50e 100644 --- a/test/libsolidity/ASTJSON/base_constructor_call.json +++ b/test/libsolidity/ASTJSON/base_constructor_call.json @@ -120,10 +120,7 @@ "src": "50:1:1" } ], - "contractDependencies": - [ - 7 - ], + "contractDependencies": [], "contractKind": "contract", "fullyImplemented": true, "id": 17, diff --git a/test/libsolidity/ASTJSON/contract_dep_order.json b/test/libsolidity/ASTJSON/contract_dep_order.json index ed96f2f7c..b65e1be7e 100644 --- a/test/libsolidity/ASTJSON/contract_dep_order.json +++ b/test/libsolidity/ASTJSON/contract_dep_order.json @@ -63,10 +63,7 @@ "src": "29:1:1" } ], - "contractDependencies": - [ - 1 - ], + "contractDependencies": [], "contractKind": "contract", "fullyImplemented": true, "id": 4, @@ -100,11 +97,7 @@ "src": "49:1:1" } ], - "contractDependencies": - [ - 1, - 4 - ], + "contractDependencies": [], "contractKind": "contract", "fullyImplemented": true, "id": 7, @@ -139,12 +132,7 @@ "src": "69:1:1" } ], - "contractDependencies": - [ - 1, - 4, - 7 - ], + "contractDependencies": [], "contractKind": "contract", "fullyImplemented": true, "id": 10, @@ -180,13 +168,7 @@ "src": "89:1:1" } ], - "contractDependencies": - [ - 1, - 4, - 7, - 10 - ], + "contractDependencies": [], "contractKind": "contract", "fullyImplemented": true, "id": 13, diff --git a/test/libsolidity/ASTJSON/inheritance_specifier.json b/test/libsolidity/ASTJSON/inheritance_specifier.json index eed5ec73d..2fb563d38 100644 --- a/test/libsolidity/ASTJSON/inheritance_specifier.json +++ b/test/libsolidity/ASTJSON/inheritance_specifier.json @@ -51,10 +51,7 @@ "src": "30:2:1" } ], - "contractDependencies": - [ - 1 - ], + "contractDependencies": [], "contractKind": "contract", "fullyImplemented": true, "id": 4, diff --git a/test/libsolidity/ASTJSON/override.json b/test/libsolidity/ASTJSON/override.json index 89fd04a77..d433342b5 100644 --- a/test/libsolidity/ASTJSON/override.json +++ b/test/libsolidity/ASTJSON/override.json @@ -12,10 +12,10 @@ ], "C": [ - 31 + 29 ] }, - "id": 32, + "id": 30, "nodeType": "SourceUnit", "nodes": [ @@ -40,7 +40,7 @@ { "id": 3, "nodeType": "Block", - "src": "36:2:1", + "src": "44:2:1", "statements": [] }, "functionSelector": "a399b6a2", @@ -63,20 +63,20 @@ "id": 2, "nodeType": "ParameterList", "parameters": [], - "src": "36:0:1" + "src": "44:0:1" }, "scope": 5, - "src": "14:24:1", + "src": "14:32:1", "stateMutability": "nonpayable", - "virtual": false, + "virtual": true, "visibility": "public" } ], - "scope": 32, - "src": "0:40:1" + "scope": 30, + "src": "0:48:1" }, { - "abstract": false, + "abstract": true, "baseContracts": [ { @@ -86,17 +86,14 @@ "name": "A", "nodeType": "IdentifierPath", "referencedDeclaration": 5, - "src": "55:1:1" + "src": "72:1:1" }, "id": 7, "nodeType": "InheritanceSpecifier", - "src": "55:1:1" + "src": "72:1:1" } ], - "contractDependencies": - [ - 5 - ], + "contractDependencies": [], "contractKind": "contract", "fullyImplemented": false, "id": 16, @@ -106,7 +103,7 @@ 5 ], "name": "B", - "nameLocation": "50:1:1", + "nameLocation": "67:1:1", "nodeType": "ContractDefinition", "nodes": [ @@ -117,26 +114,26 @@ "kind": "function", "modifiers": [], "name": "foo", - "nameLocation": "69:3:1", + "nameLocation": "86:3:1", "nodeType": "FunctionDefinition", "parameters": { "id": 8, "nodeType": "ParameterList", "parameters": [], - "src": "72:2:1" + "src": "89:2:1" }, "returnParameters": { "id": 9, "nodeType": "ParameterList", "parameters": [], - "src": "81:0:1" + "src": "106:0:1" }, "scope": 16, - "src": "60:22:1", + "src": "77:30:1", "stateMutability": "nonpayable", - "virtual": false, + "virtual": true, "visibility": "public" }, { @@ -148,7 +145,7 @@ { "id": 14, "nodeType": "Block", - "src": "115:2:1", + "src": "148:2:1", "statements": [] }, "functionSelector": "a399b6a2", @@ -157,38 +154,38 @@ "kind": "function", "modifiers": [], "name": "faa", - "nameLocation": "93:3:1", + "nameLocation": "118:3:1", "nodeType": "FunctionDefinition", "overrides": { "id": 12, "nodeType": "OverrideSpecifier", "overrides": [], - "src": "106:8:1" + "src": "139:8:1" }, "parameters": { "id": 11, "nodeType": "ParameterList", "parameters": [], - "src": "96:2:1" + "src": "121:2:1" }, "returnParameters": { "id": 13, "nodeType": "ParameterList", "parameters": [], - "src": "115:0:1" + "src": "148:0:1" }, "scope": 16, - "src": "84:33:1", + "src": "109:41:1", "stateMutability": "nonpayable", - "virtual": false, + "virtual": true, "visibility": "public" } ], - "scope": 32, - "src": "41:78:1" + "scope": 30, + "src": "49:103:1" }, { "abstract": false, @@ -201,29 +198,25 @@ "name": "B", "nodeType": "IdentifierPath", "referencedDeclaration": 16, - "src": "134:1:1" + "src": "167:1:1" }, "id": 18, "nodeType": "InheritanceSpecifier", - "src": "134:1:1" + "src": "167:1:1" } ], - "contractDependencies": - [ - 5, - 16 - ], + "contractDependencies": [], "contractKind": "contract", "fullyImplemented": true, - "id": 31, + "id": 29, "linearizedBaseContracts": [ - 31, + 29, 16, 5 ], "name": "C", - "nameLocation": "129:1:1", + "nameLocation": "162:1:1", "nodeType": "ContractDefinition", "nodes": [ @@ -236,7 +229,7 @@ { "id": 22, "nodeType": "Block", - "src": "170:3:1", + "src": "203:3:1", "statements": [] }, "functionSelector": "c2985578", @@ -245,31 +238,31 @@ "kind": "function", "modifiers": [], "name": "foo", - "nameLocation": "148:3:1", + "nameLocation": "181:3:1", "nodeType": "FunctionDefinition", "overrides": { "id": 20, "nodeType": "OverrideSpecifier", "overrides": [], - "src": "161:8:1" + "src": "194:8:1" }, "parameters": { "id": 19, "nodeType": "ParameterList", "parameters": [], - "src": "151:2:1" + "src": "184:2:1" }, "returnParameters": { "id": 21, "nodeType": "ParameterList", "parameters": [], - "src": "170:0:1" + "src": "203:0:1" }, - "scope": 31, - "src": "139:34:1", + "scope": 29, + "src": "172:34:1", "stateMutability": "nonpayable", "virtual": false, "visibility": "public" @@ -281,66 +274,50 @@ ], "body": { - "id": 29, + "id": 27, "nodeType": "Block", - "src": "212:2:1", + "src": "239:3:1", "statements": [] }, "functionSelector": "a399b6a2", - "id": 30, + "id": 28, "implemented": true, "kind": "function", "modifiers": [], "name": "faa", - "nameLocation": "184:3:1", + "nameLocation": "217:3:1", "nodeType": "FunctionDefinition", "overrides": { - "id": 27, + "id": 25, "nodeType": "OverrideSpecifier", - "overrides": - [ - { - "id": 25, - "name": "A", - "nodeType": "IdentifierPath", - "referencedDeclaration": 5, - "src": "206:1:1" - }, - { - "id": 26, - "name": "B", - "nodeType": "IdentifierPath", - "referencedDeclaration": 16, - "src": "209:1:1" - } - ], - "src": "197:14:1" + "overrides": [], + "src": "230:8:1" }, "parameters": { "id": 24, "nodeType": "ParameterList", "parameters": [], - "src": "187:2:1" + "src": "220:2:1" }, "returnParameters": { - "id": 28, + "id": 26, "nodeType": "ParameterList", "parameters": [], - "src": "212:0:1" + "src": "239:0:1" }, - "scope": 31, - "src": "175:39:1", + "scope": 29, + "src": "208:34:1", "stateMutability": "nonpayable", "virtual": false, "visibility": "public" } ], - "scope": 32, - "src": "120:96:1" + "scope": 30, + "src": "153:91:1" } ], - "src": "0:217:1" + "src": "0:245:1" } diff --git a/test/libsolidity/ASTJSON/override.sol b/test/libsolidity/ASTJSON/override.sol index 3edb20df0..1aaa58c60 100644 --- a/test/libsolidity/ASTJSON/override.sol +++ b/test/libsolidity/ASTJSON/override.sol @@ -1,13 +1,13 @@ contract A { - function faa() public {} + function faa() public virtual {} } -contract B is A { - function foo() public; - function faa() public override {} +abstract contract B is A { + function foo() public virtual; + function faa() public virtual override {} } contract C is B { function foo() public override { } - function faa() public override(A, B) {} + function faa() public override { } } // ---- diff --git a/test/libsolidity/ASTJSON/override_parseOnly.json b/test/libsolidity/ASTJSON/override_parseOnly.json index fb9b3e566..d75b9b8e5 100644 --- a/test/libsolidity/ASTJSON/override_parseOnly.json +++ b/test/libsolidity/ASTJSON/override_parseOnly.json @@ -1,6 +1,6 @@ { "absolutePath": "a", - "id": 32, + "id": 30, "nodeType": "SourceUnit", "nodes": [ @@ -20,7 +20,7 @@ { "id": 3, "nodeType": "Block", - "src": "36:2:1", + "src": "44:2:1", "statements": [] }, "id": 4, @@ -42,18 +42,18 @@ "id": 2, "nodeType": "ParameterList", "parameters": [], - "src": "36:0:1" + "src": "44:0:1" }, - "src": "14:24:1", + "src": "14:32:1", "stateMutability": "nonpayable", - "virtual": false, + "virtual": true, "visibility": "public" } ], - "src": "0:40:1" + "src": "0:48:1" }, { - "abstract": false, + "abstract": true, "baseContracts": [ { @@ -62,18 +62,18 @@ "id": 6, "name": "A", "nodeType": "IdentifierPath", - "src": "55:1:1" + "src": "72:1:1" }, "id": 7, "nodeType": "InheritanceSpecifier", - "src": "55:1:1" + "src": "72:1:1" } ], "contractDependencies": [], "contractKind": "contract", "id": 16, "name": "B", - "nameLocation": "50:1:1", + "nameLocation": "67:1:1", "nodeType": "ContractDefinition", "nodes": [ @@ -83,25 +83,25 @@ "kind": "function", "modifiers": [], "name": "foo", - "nameLocation": "69:3:1", + "nameLocation": "86:3:1", "nodeType": "FunctionDefinition", "parameters": { "id": 8, "nodeType": "ParameterList", "parameters": [], - "src": "72:2:1" + "src": "89:2:1" }, "returnParameters": { "id": 9, "nodeType": "ParameterList", "parameters": [], - "src": "81:0:1" + "src": "106:0:1" }, - "src": "60:22:1", + "src": "77:30:1", "stateMutability": "nonpayable", - "virtual": false, + "virtual": true, "visibility": "public" }, { @@ -109,7 +109,7 @@ { "id": 14, "nodeType": "Block", - "src": "115:2:1", + "src": "148:2:1", "statements": [] }, "id": 15, @@ -117,36 +117,36 @@ "kind": "function", "modifiers": [], "name": "faa", - "nameLocation": "93:3:1", + "nameLocation": "118:3:1", "nodeType": "FunctionDefinition", "overrides": { "id": 12, "nodeType": "OverrideSpecifier", "overrides": [], - "src": "106:8:1" + "src": "139:8:1" }, "parameters": { "id": 11, "nodeType": "ParameterList", "parameters": [], - "src": "96:2:1" + "src": "121:2:1" }, "returnParameters": { "id": 13, "nodeType": "ParameterList", "parameters": [], - "src": "115:0:1" + "src": "148:0:1" }, - "src": "84:33:1", + "src": "109:41:1", "stateMutability": "nonpayable", - "virtual": false, + "virtual": true, "visibility": "public" } ], - "src": "41:78:1" + "src": "49:103:1" }, { "abstract": false, @@ -158,18 +158,18 @@ "id": 17, "name": "B", "nodeType": "IdentifierPath", - "src": "134:1:1" + "src": "167:1:1" }, "id": 18, "nodeType": "InheritanceSpecifier", - "src": "134:1:1" + "src": "167:1:1" } ], "contractDependencies": [], "contractKind": "contract", - "id": 31, + "id": 29, "name": "C", - "nameLocation": "129:1:1", + "nameLocation": "162:1:1", "nodeType": "ContractDefinition", "nodes": [ @@ -178,7 +178,7 @@ { "id": 22, "nodeType": "Block", - "src": "170:3:1", + "src": "203:3:1", "statements": [] }, "id": 23, @@ -186,30 +186,30 @@ "kind": "function", "modifiers": [], "name": "foo", - "nameLocation": "148:3:1", + "nameLocation": "181:3:1", "nodeType": "FunctionDefinition", "overrides": { "id": 20, "nodeType": "OverrideSpecifier", "overrides": [], - "src": "161:8:1" + "src": "194:8:1" }, "parameters": { "id": 19, "nodeType": "ParameterList", "parameters": [], - "src": "151:2:1" + "src": "184:2:1" }, "returnParameters": { "id": 21, "nodeType": "ParameterList", "parameters": [], - "src": "170:0:1" + "src": "203:0:1" }, - "src": "139:34:1", + "src": "172:34:1", "stateMutability": "nonpayable", "virtual": false, "visibility": "public" @@ -217,61 +217,47 @@ { "body": { - "id": 29, + "id": 27, "nodeType": "Block", - "src": "212:2:1", + "src": "239:3:1", "statements": [] }, - "id": 30, + "id": 28, "implemented": true, "kind": "function", "modifiers": [], "name": "faa", - "nameLocation": "184:3:1", + "nameLocation": "217:3:1", "nodeType": "FunctionDefinition", "overrides": { - "id": 27, + "id": 25, "nodeType": "OverrideSpecifier", - "overrides": - [ - { - "id": 25, - "name": "A", - "nodeType": "IdentifierPath", - "src": "206:1:1" - }, - { - "id": 26, - "name": "B", - "nodeType": "IdentifierPath", - "src": "209:1:1" - } - ], - "src": "197:14:1" + "overrides": [], + "src": "230:8:1" }, "parameters": { "id": 24, "nodeType": "ParameterList", "parameters": [], - "src": "187:2:1" + "src": "220:2:1" }, "returnParameters": { - "id": 28, + "id": 26, "nodeType": "ParameterList", "parameters": [], - "src": "212:0:1" + "src": "239:0:1" }, - "src": "175:39:1", + "src": "208:34:1", "stateMutability": "nonpayable", "virtual": false, "visibility": "public" } ], - "src": "120:96:1" + "src": "153:91:1" } ], - "src": "0:217:1" + "src": "0:245:1" } diff --git a/test/libsolidity/ASTJSON/two_base_functions.json b/test/libsolidity/ASTJSON/two_base_functions.json index 45f1c0046..f6c7a176e 100644 --- a/test/libsolidity/ASTJSON/two_base_functions.json +++ b/test/libsolidity/ASTJSON/two_base_functions.json @@ -162,11 +162,7 @@ "src": "117:1:1" } ], - "contractDependencies": - [ - 5, - 10 - ], + "contractDependencies": [], "contractKind": "contract", "fullyImplemented": true, "id": 22, diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_complex.sol b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_complex.sol new file mode 100644 index 000000000..dd8983607 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_complex.sol @@ -0,0 +1,7 @@ +contract D {} +contract C is D {} +contract E is D +{ + function foo() public { new C(); } +} +// ---- diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_complex1.sol b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_complex1.sol new file mode 100644 index 000000000..548b9186d --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_complex1.sol @@ -0,0 +1,6 @@ +contract A { function foo() public { new D(); } } +contract C { function foo() public { new A(); } } +contract D is C {} +// ---- +// TypeError 7813: (37-42): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". +// TypeError 7813: (87-92): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_free_function.sol b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_free_function.sol new file mode 100644 index 000000000..13d998d0b --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_free_function.sol @@ -0,0 +1,11 @@ +function f() +{ + new D(); +} + +contract D +{ + receive() external payable { f; } +} +// ---- +// TypeError 7813: (16-21): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_function_parameters.sol b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_function_parameters.sol new file mode 100644 index 000000000..ea93a44b8 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_function_parameters.sol @@ -0,0 +1,3 @@ +contract C { function foo(D _d) public { _d.foo(this); } } +contract D { function foo(C _c) public { _c.foo(this); } } +// ---- diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_function.sol b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_function.sol new file mode 100644 index 000000000..7596797c6 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_function.sol @@ -0,0 +1,11 @@ +contract C +{ + // Internal uncalled function should not cause an cyclic dep. error + function foo() internal { new D(); } + function callFoo() virtual public { foo(); } +} + +contract D is C +{ + function callFoo() override public {} +} diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_functions.sol b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_functions.sol new file mode 100644 index 000000000..8c60a87a6 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_functions.sol @@ -0,0 +1,3 @@ +contract C { function foo() internal { new D(); } } +contract D { function foo() internal { new C(); } } +// ---- diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_libraries.sol b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_libraries.sol new file mode 100644 index 000000000..ee551a605 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_libraries.sol @@ -0,0 +1,3 @@ +library L1 { function foo() internal { L2.foo(); } } +library L2 { function foo() internal { L1.foo(); } } +// ---- diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_mention_only.sol b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_mention_only.sol new file mode 100644 index 000000000..9fc697727 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_mention_only.sol @@ -0,0 +1,9 @@ +contract C { + function foo() public pure { D; } +} +contract D { + function foo() public pure { C; } +} +// ---- +// Warning 6133: (43-44): Statement has no effect. +// Warning 6133: (93-94): Statement has no effect. diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_new_in_ctor.sol b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_new_in_ctor.sol new file mode 100644 index 000000000..c99a7b104 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_new_in_ctor.sol @@ -0,0 +1,5 @@ +contract C { + constructor() { new C(); } +} +// ---- +// TypeError 7813: (30-35): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_report_first_in_cycle.sol b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_report_first_in_cycle.sol new file mode 100644 index 000000000..a204c4448 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_report_first_in_cycle.sol @@ -0,0 +1,13 @@ +contract A { B x = new B(); } +contract B { C x = new C(); } +contract C { D x = new D(); } +contract D { E x = new E(); } +contract E { F x = new F(); } +contract F { E x = new E(); } +// ---- +// TypeError 7813: (19-24): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". +// TypeError 7813: (49-54): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". +// TypeError 7813: (79-84): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". +// TypeError 7813: (109-114): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". +// TypeError 7813: (139-144): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". +// TypeError 7813: (169-174): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_type_mention_only.sol b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_type_mention_only.sol new file mode 100644 index 000000000..ce6b101f5 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_type_mention_only.sol @@ -0,0 +1,9 @@ +contract C { + function foo() public pure { type(D); } +} +contract D { + function foo() public pure { type(C); } +} +// ---- +// Warning 6133: (43-50): Statement has no effect. +// Warning 6133: (99-106): Statement has no effect. diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/cyclic_dep_exhaustion.sol b/test/libsolidity/syntaxTests/bytecodeReferences/cyclic_dep_exhaustion.sol new file mode 100644 index 000000000..44a1a538d --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecodeReferences/cyclic_dep_exhaustion.sol @@ -0,0 +1,773 @@ +contract D { + function f() public { + new C(); + } +} +contract C { + constructor() { new C2(); } +} +contract C2 { + constructor() { new C3(); } +} +contract C3 { + constructor() { new C4(); } +} +contract C4 { + constructor() { new C5(); } +} +contract C5 { + constructor() { new C6(); } +} +contract C6 { + constructor() { new C7(); } +} +contract C7 { + constructor() { new C8(); } +} +contract C8 { + constructor() { new C9(); } +} +contract C9 { + constructor() { new C10(); } +} +contract C10 { + constructor() { new C11(); } +} +contract C11 { + constructor() { new C12(); } +} +contract C12 { + constructor() { new C13(); } +} +contract C13 { + constructor() { new C14(); } +} +contract C14 { + constructor() { new C15(); } +} +contract C15 { + constructor() { new C16(); } +} +contract C16 { + constructor() { new C17(); } +} +contract C17 { + constructor() { new C18(); } +} +contract C18 { + constructor() { new C19(); } +} +contract C19 { + constructor() { new C20(); } +} +contract C20 { + constructor() { new C21(); } +} +contract C21 { + constructor() { new C22(); } +} +contract C22 { + constructor() { new C23(); } +} +contract C23 { + constructor() { new C24(); } +} +contract C24 { + constructor() { new C25(); } +} +contract C25 { + constructor() { new C26(); } +} +contract C26 { + constructor() { new C27(); } +} +contract C27 { + constructor() { new C28(); } +} +contract C28 { + constructor() { new C29(); } +} +contract C29 { + constructor() { new C30(); } +} +contract C30 { + constructor() { new C31(); } +} +contract C31 { + constructor() { new C32(); } +} +contract C32 { + constructor() { new C33(); } +} +contract C33 { + constructor() { new C34(); } +} +contract C34 { + constructor() { new C35(); } +} +contract C35 { + constructor() { new C36(); } +} +contract C36 { + constructor() { new C37(); } +} +contract C37 { + constructor() { new C38(); } +} +contract C38 { + constructor() { new C39(); } +} +contract C39 { + constructor() { new C40(); } +} +contract C40 { + constructor() { new C41(); } +} +contract C41 { + constructor() { new C42(); } +} +contract C42 { + constructor() { new C43(); } +} +contract C43 { + constructor() { new C44(); } +} +contract C44 { + constructor() { new C45(); } +} +contract C45 { + constructor() { new C46(); } +} +contract C46 { + constructor() { new C47(); } +} +contract C47 { + constructor() { new C48(); } +} +contract C48 { + constructor() { new C49(); } +} +contract C49 { + constructor() { new C50(); } +} +contract C50 { + constructor() { new C51(); } +} +contract C51 { + constructor() { new C52(); } +} +contract C52 { + constructor() { new C53(); } +} +contract C53 { + constructor() { new C54(); } +} +contract C54 { + constructor() { new C55(); } +} +contract C55 { + constructor() { new C56(); } +} +contract C56 { + constructor() { new C57(); } +} +contract C57 { + constructor() { new C58(); } +} +contract C58 { + constructor() { new C59(); } +} +contract C59 { + constructor() { new C60(); } +} +contract C60 { + constructor() { new C61(); } +} +contract C61 { + constructor() { new C62(); } +} +contract C62 { + constructor() { new C63(); } +} +contract C63 { + constructor() { new C64(); } +} +contract C64 { + constructor() { new C65(); } +} +contract C65 { + constructor() { new C66(); } +} +contract C66 { + constructor() { new C67(); } +} +contract C67 { + constructor() { new C68(); } +} +contract C68 { + constructor() { new C69(); } +} +contract C69 { + constructor() { new C70(); } +} +contract C70 { + constructor() { new C71(); } +} +contract C71 { + constructor() { new C72(); } +} +contract C72 { + constructor() { new C73(); } +} +contract C73 { + constructor() { new C74(); } +} +contract C74 { + constructor() { new C75(); } +} +contract C75 { + constructor() { new C76(); } +} +contract C76 { + constructor() { new C77(); } +} +contract C77 { + constructor() { new C78(); } +} +contract C78 { + constructor() { new C79(); } +} +contract C79 { + constructor() { new C80(); } +} +contract C80 { + constructor() { new C81(); } +} +contract C81 { + constructor() { new C82(); } +} +contract C82 { + constructor() { new C83(); } +} +contract C83 { + constructor() { new C84(); } +} +contract C84 { + constructor() { new C85(); } +} +contract C85 { + constructor() { new C86(); } +} +contract C86 { + constructor() { new C87(); } +} +contract C87 { + constructor() { new C88(); } +} +contract C88 { + constructor() { new C89(); } +} +contract C89 { + constructor() { new C90(); } +} +contract C90 { + constructor() { new C91(); } +} +contract C91 { + constructor() { new C92(); } +} +contract C92 { + constructor() { new C93(); } +} +contract C93 { + constructor() { new C94(); } +} +contract C94 { + constructor() { new C95(); } +} +contract C95 { + constructor() { new C96(); } +} +contract C96 { + constructor() { new C97(); } +} +contract C97 { + constructor() { new C98(); } +} +contract C98 { + constructor() { new C99(); } +} +contract C99 { + constructor() { new C100(); } +} +contract C100 { + constructor() { new C101(); } +} +contract C101 { + constructor() { new C102(); } +} +contract C102 { + constructor() { new C103(); } +} +contract C103 { + constructor() { new C104(); } +} +contract C104 { + constructor() { new C105(); } +} +contract C105 { + constructor() { new C106(); } +} +contract C106 { + constructor() { new C107(); } +} +contract C107 { + constructor() { new C108(); } +} +contract C108 { + constructor() { new C109(); } +} +contract C109 { + constructor() { new C110(); } +} +contract C110 { + constructor() { new C111(); } +} +contract C111 { + constructor() { new C112(); } +} +contract C112 { + constructor() { new C113(); } +} +contract C113 { + constructor() { new C114(); } +} +contract C114 { + constructor() { new C115(); } +} +contract C115 { + constructor() { new C116(); } +} +contract C116 { + constructor() { new C117(); } +} +contract C117 { + constructor() { new C118(); } +} +contract C118 { + constructor() { new C119(); } +} +contract C119 { + constructor() { new C120(); } +} +contract C120 { + constructor() { new C121(); } +} +contract C121 { + constructor() { new C122(); } +} +contract C122 { + constructor() { new C123(); } +} +contract C123 { + constructor() { new C124(); } +} +contract C124 { + constructor() { new C125(); } +} +contract C125 { + constructor() { new C126(); } +} +contract C126 { + constructor() { new C127(); } +} +contract C127 { + constructor() { new C128(); } +} +contract C128 { + constructor() { new C129(); } +} +contract C129 { + constructor() { new C130(); } +} +contract C130 { + constructor() { new C131(); } +} +contract C131 { + constructor() { new C132(); } +} +contract C132 { + constructor() { new C133(); } +} +contract C133 { + constructor() { new C134(); } +} +contract C134 { + constructor() { new C135(); } +} +contract C135 { + constructor() { new C136(); } +} +contract C136 { + constructor() { new C137(); } +} +contract C137 { + constructor() { new C138(); } +} +contract C138 { + constructor() { new C139(); } +} +contract C139 { + constructor() { new C140(); } +} +contract C140 { + constructor() { new C141(); } +} +contract C141 { + constructor() { new C142(); } +} +contract C142 { + constructor() { new C143(); } +} +contract C143 { + constructor() { new C144(); } +} +contract C144 { + constructor() { new C145(); } +} +contract C145 { + constructor() { new C146(); } +} +contract C146 { + constructor() { new C147(); } +} +contract C147 { + constructor() { new C148(); } +} +contract C148 { + constructor() { new C149(); } +} +contract C149 { + constructor() { new C150(); } +} +contract C150 { + constructor() { new C151(); } +} +contract C151 { + constructor() { new C152(); } +} +contract C152 { + constructor() { new C153(); } +} +contract C153 { + constructor() { new C154(); } +} +contract C154 { + constructor() { new C155(); } +} +contract C155 { + constructor() { new C156(); } +} +contract C156 { + constructor() { new C157(); } +} +contract C157 { + constructor() { new C158(); } +} +contract C158 { + constructor() { new C159(); } +} +contract C159 { + constructor() { new C160(); } +} +contract C160 { + constructor() { new C161(); } +} +contract C161 { + constructor() { new C162(); } +} +contract C162 { + constructor() { new C163(); } +} +contract C163 { + constructor() { new C164(); } +} +contract C164 { + constructor() { new C165(); } +} +contract C165 { + constructor() { new C166(); } +} +contract C166 { + constructor() { new C167(); } +} +contract C167 { + constructor() { new C168(); } +} +contract C168 { + constructor() { new C169(); } +} +contract C169 { + constructor() { new C170(); } +} +contract C170 { + constructor() { new C171(); } +} +contract C171 { + constructor() { new C172(); } +} +contract C172 { + constructor() { new C173(); } +} +contract C173 { + constructor() { new C174(); } +} +contract C174 { + constructor() { new C175(); } +} +contract C175 { + constructor() { new C176(); } +} +contract C176 { + constructor() { new C177(); } +} +contract C177 { + constructor() { new C178(); } +} +contract C178 { + constructor() { new C179(); } +} +contract C179 { + constructor() { new C180(); } +} +contract C180 { + constructor() { new C181(); } +} +contract C181 { + constructor() { new C182(); } +} +contract C182 { + constructor() { new C183(); } +} +contract C183 { + constructor() { new C184(); } +} +contract C184 { + constructor() { new C185(); } +} +contract C185 { + constructor() { new C186(); } +} +contract C186 { + constructor() { new C187(); } +} +contract C187 { + constructor() { new C188(); } +} +contract C188 { + constructor() { new C189(); } +} +contract C189 { + constructor() { new C190(); } +} +contract C190 { + constructor() { new C191(); } +} +contract C191 { + constructor() { new C192(); } +} +contract C192 { + constructor() { new C193(); } +} +contract C193 { + constructor() { new C194(); } +} +contract C194 { + constructor() { new C195(); } +} +contract C195 { + constructor() { new C196(); } +} +contract C196 { + constructor() { new C197(); } +} +contract C197 { + constructor() { new C198(); } +} +contract C198 { + constructor() { new C199(); } +} +contract C199 { + constructor() { new C200(); } +} +contract C200 { + constructor() { new C201(); } +} +contract C201 { + constructor() { new C202(); } +} +contract C202 { + constructor() { new C203(); } +} +contract C203 { + constructor() { new C204(); } +} +contract C204 { + constructor() { new C205(); } +} +contract C205 { + constructor() { new C206(); } +} +contract C206 { + constructor() { new C207(); } +} +contract C207 { + constructor() { new C208(); } +} +contract C208 { + constructor() { new C209(); } +} +contract C209 { + constructor() { new C210(); } +} +contract C210 { + constructor() { new C211(); } +} +contract C211 { + constructor() { new C212(); } +} +contract C212 { + constructor() { new C213(); } +} +contract C213 { + constructor() { new C214(); } +} +contract C214 { + constructor() { new C215(); } +} +contract C215 { + constructor() { new C216(); } +} +contract C216 { + constructor() { new C217(); } +} +contract C217 { + constructor() { new C218(); } +} +contract C218 { + constructor() { new C219(); } +} +contract C219 { + constructor() { new C220(); } +} +contract C220 { + constructor() { new C221(); } +} +contract C221 { + constructor() { new C222(); } +} +contract C222 { + constructor() { new C223(); } +} +contract C223 { + constructor() { new C224(); } +} +contract C224 { + constructor() { new C225(); } +} +contract C225 { + constructor() { new C226(); } +} +contract C226 { + constructor() { new C227(); } +} +contract C227 { + constructor() { new C228(); } +} +contract C228 { + constructor() { new C229(); } +} +contract C229 { + constructor() { new C230(); } +} +contract C230 { + constructor() { new C231(); } +} +contract C231 { + constructor() { new C232(); } +} +contract C232 { + constructor() { new C233(); } +} +contract C233 { + constructor() { new C234(); } +} +contract C234 { + constructor() { new C235(); } +} +contract C235 { + constructor() { new C236(); } +} +contract C236 { + constructor() { new C237(); } +} +contract C237 { + constructor() { new C238(); } +} +contract C238 { + constructor() { new C239(); } +} +contract C239 { + constructor() { new C240(); } +} +contract C240 { + constructor() { new C241(); } +} +contract C241 { + constructor() { new C242(); } +} +contract C242 { + constructor() { new C243(); } +} +contract C243 { + constructor() { new C244(); } +} +contract C244 { + constructor() { new C245(); } +} +contract C245 { + constructor() { new C246(); } +} +contract C246 { + constructor() { new C247(); } +} +contract C247 { + constructor() { new C248(); } +} +contract C248 { + constructor() { new C249(); } +} +contract C249 { + constructor() { new C250(); } +} +contract C250 { + constructor() { new C251(); } +} +contract C251 { + constructor() { new C252(); } +} +contract C252 { + constructor() { new C253(); } +} +contract C253 { + constructor() { new C254(); } +} +contract C254 { + constructor() { new C255(); } +} +contract C255 { + constructor() { new C(); } +} + +// ---- +// TypeError 7864: (13057-13105): Contract dependencies exhausting cyclic dependency validator diff --git a/test/libsolidity/syntaxTests/bytecodeReferences/library_function_circular_reference.sol b/test/libsolidity/syntaxTests/bytecodeReferences/library_function_circular_reference.sol new file mode 100644 index 000000000..53ecc0755 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecodeReferences/library_function_circular_reference.sol @@ -0,0 +1,18 @@ +library L { + function f() internal { + new C(); + } +} + +contract D { + function f() public { + L.f(); + } +} +contract C { + constructor() { new D(); } +} + +// ---- +// TypeError 7813: (48-53): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". +// TypeError 7813: (161-166): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". diff --git a/test/libsolidity/syntaxTests/freeFunctions/circular_reference1functions_first.sol b/test/libsolidity/syntaxTests/freeFunctions/circular_reference1functions_first.sol new file mode 100644 index 000000000..a76cbf28f --- /dev/null +++ b/test/libsolidity/syntaxTests/freeFunctions/circular_reference1functions_first.sol @@ -0,0 +1,18 @@ +// Checks that error is triggered no matter which order +function l() { + s(); +} +function s() { + new C(); +} +contract D { + function f() public { + l(); + } +} +contract C { + constructor() { new D(); } +} +// ---- +// TypeError 7813: (98-103): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". +// TypeError 7813: (187-192): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". diff --git a/test/libsolidity/syntaxTests/freeFunctions/circular_referencecontracts_first.sol b/test/libsolidity/syntaxTests/freeFunctions/circular_referencecontracts_first.sol new file mode 100644 index 000000000..62879fe02 --- /dev/null +++ b/test/libsolidity/syntaxTests/freeFunctions/circular_referencecontracts_first.sol @@ -0,0 +1,18 @@ +// Checks that error is triggered no matter which order +contract D { + function f() public { + l(); + } +} +contract C { + constructor() { new D(); } +} +function l() { + s(); +} +function s() { + new C(); +} +// ---- +// TypeError 7813: (207-212): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". +// TypeError 7813: (149-154): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". diff --git a/test/libsolidity/syntaxTests/metaTypes/codeAccessBase.sol b/test/libsolidity/syntaxTests/metaTypes/codeAccessBase.sol index 33a58c648..c202046cc 100644 --- a/test/libsolidity/syntaxTests/metaTypes/codeAccessBase.sol +++ b/test/libsolidity/syntaxTests/metaTypes/codeAccessBase.sol @@ -1,22 +1,26 @@ contract Base { function f() public pure returns (uint) {} } -contract Test is Base { +contract Test1 is Base { function creation() public pure returns (bytes memory) { - return type(Test).creationCode; + return type(Test1).creationCode; } +} +contract Test2 is Base { function runtime() public pure returns (bytes memory) { - return type(Test).runtimeCode; + return type(Test2).runtimeCode; } +} +contract Test3 is Base { function creationBase() public pure returns (bytes memory) { return type(Base).creationCode; } +} +contract Test4 is Base { function runtimeBase() public pure returns (bytes memory) { return type(Base).runtimeCode; } } // ---- -// TypeError 4224: (165-188): Circular reference for contract code access. -// TypeError 4224: (271-293): Circular reference for contract code access. -// TypeError 4224: (381-404): Circular reference for contract code access. -// TypeError 4224: (491-513): Circular reference for contract code access. +// TypeError 7813: (166-190): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". +// TypeError 7813: (300-323): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". diff --git a/test/libsolidity/syntaxTests/metaTypes/codeAccessCyclic.sol b/test/libsolidity/syntaxTests/metaTypes/codeAccessCyclic.sol index e27b2cd3b..57e3263e3 100644 --- a/test/libsolidity/syntaxTests/metaTypes/codeAccessCyclic.sol +++ b/test/libsolidity/syntaxTests/metaTypes/codeAccessCyclic.sol @@ -9,4 +9,5 @@ contract B { } } // ---- -// TypeError 4224: (133-152): Circular reference for contract code access. +// TypeError 7813: (52-71): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". +// TypeError 7813: (133-152): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/230_creating_contract_within_the_contract.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/230_creating_contract_within_the_contract.sol index 25f742496..738031b0c 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/230_creating_contract_within_the_contract.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/230_creating_contract_within_the_contract.sol @@ -2,4 +2,4 @@ contract Test { function f() public { Test x = new Test(); } } // ---- -// TypeError 4579: (51-59): Circular reference for contract creation (cannot create instance of derived or same contract). +// TypeError 7813: (51-59): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/236_cyclic_binary_dependency.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/236_cyclic_binary_dependency.sol index c39812aa6..1686a9f07 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/236_cyclic_binary_dependency.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/236_cyclic_binary_dependency.sol @@ -2,4 +2,6 @@ contract A { function f() public { new B(); } } contract B { function f() public { new C(); } } contract C { function f() public { new A(); } } // ---- -// TypeError 4579: (131-136): Circular reference for contract creation (cannot create instance of derived or same contract). +// TypeError 7813: (35-40): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". +// TypeError 7813: (83-88): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode". +// TypeError 7813: (131-136): Circular reference to contract bytecode either via "new" or "type(...).creationCode" / "type(...).runtimeCode".