From 3eaa37030a10c74a0d5d046f165ce84864dec068 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 8 Jun 2021 12:43:43 +0200 Subject: [PATCH] Fix infinite recursion in function call graph generator due to recursive constant references. --- Changelog.md | 1 + libsolidity/interface/CompilerStack.cpp | 14 +++++++------- .../syntaxTests/constants/cyclic_dependency_5.sol | 8 ++++++++ 3 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 test/libsolidity/syntaxTests/constants/cyclic_dependency_5.sol diff --git a/Changelog.md b/Changelog.md index 354eb6414..0bedeb7d6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -20,6 +20,7 @@ Bugfixes: * Code Generator: Fix internal error when super would have to skip an unimplemented function in the virtual resolution order. * Control Flow Graph: Take internal calls to functions that always revert into account for reporting unused or unassigned variables. * Control Flow Graph: Assume unimplemented modifiers use a placeholder. + * Function Call Graph: Fix internal error connected with circular constant references. * Natspec: Allow multiple ``@return`` tags on public state variable documentation. * SMTChecker: Fix internal error on struct constructor with fixed bytes member initialized with string literal. * SMTChecker: Fix internal error on external calls from the constructor. diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 00919ddba..35e497f9a 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -480,13 +480,6 @@ bool CompilerStack::analyze() if (source->ast && !typeChecker.checkTypeRequirements(*source->ast)) noErrors = false; - // Create & assign callgraphs and check for contract dependency cycles - if (noErrors) - { - createAndAssignCallGraphs(); - findAndReportCyclicContractDependencies(); - } - if (noErrors) { // Checks that can only be done when all types of all AST nodes are known. @@ -498,6 +491,13 @@ bool CompilerStack::analyze() noErrors = false; } + // Create & assign callgraphs and check for contract dependency cycles + if (noErrors) + { + createAndAssignCallGraphs(); + findAndReportCyclicContractDependencies(); + } + if (noErrors) for (Source const* source: m_sourceOrder) if (source->ast && !PostTypeContractLevelChecker{m_errorReporter}.check(*source->ast)) diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_5.sol b/test/libsolidity/syntaxTests/constants/cyclic_dependency_5.sol new file mode 100644 index 000000000..b8a5b49ae --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/cyclic_dependency_5.sol @@ -0,0 +1,8 @@ +contract C { + uint constant a = uint(keccak256(abi.encode(d))); + uint c = uint(keccak256(abi.encode(d))); + uint constant d = a; +} +// ---- +// TypeError 6161: (15-63): The value of the constant a has a cyclic dependency via d. +// TypeError 6161: (110-129): The value of the constant d has a cyclic dependency via a.