Fix StandardCompiler returning an incomplete AST in Standard JSON in case of an early exit during analysis

This commit is contained in:
Kamil Śliwak 2023-06-14 12:02:24 +02:00
parent f50820fcae
commit 712229a5c6
4 changed files with 12 additions and 112 deletions

View File

@ -19,6 +19,7 @@ Bugfixes:
* Commandline Interface: It is no longer possible to specify both ``--optimize-yul`` and ``--no-optimize-yul`` at the same time.
* SMTChecker: Fix encoding of side-effects inside ``if`` and ``ternary conditional``statements in the BMC engine.
* SMTChecker: Fix false negative when a verification target can be violated only by trusted external call from another public function.
* Standard JSON Interface: Fix an incomplete AST being returned when analysis is interrupted by certain kinds of fatal errors.
* Yul Optimizer: Ensure that the assignment of memory slots for variables moved to memory does not depend on AST IDs that may depend on whether additional files are included during compilation.
* Yul Optimizer: Fix optimized IR being unnecessarily passed through the Yul optimizer again before bytecode generation.

View File

@ -1305,15 +1305,21 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
));
}
bool parsingSuccess = compilerStack.state() >= CompilerStack::State::Parsed;
bool analysisPerformed = compilerStack.state() >= CompilerStack::State::AnalysisPerformed;
bool const compilationSuccess = compilerStack.state() == CompilerStack::State::CompilationSuccessful;
bool compilationSuccess = compilerStack.state() == CompilerStack::State::CompilationSuccessful;
if (compilerStack.hasError() && !_inputsAndSettings.parserErrorRecovery)
analysisPerformed = false;
// If analysis fails, the artifacts inside CompilerStack are potentially incomplete and must not be returned.
// Note that not completing analysis due to stopAfter does not count as a failure. It's neither failure nor success.
bool analysisFailed = !analysisPerformed && _inputsAndSettings.stopAfter >= CompilerStack::State::AnalysisPerformed;
bool compilationFailed = !compilationSuccess && binariesRequested;
/// Inconsistent state - stop here to receive error reports from users
if (
((binariesRequested && !compilationSuccess) || !analysisPerformed) &&
(compilationFailed || !analysisPerformed) &&
(errors.empty() && _inputsAndSettings.stopAfter >= CompilerStack::State::AnalysisPerformed)
)
return formatFatalError(Error::Type::InternalCompilerError, "No error reported, but compilation failed.");
@ -1331,7 +1337,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
output["sources"] = Json::objectValue;
unsigned sourceIndex = 0;
if (compilerStack.state() >= CompilerStack::State::Parsed && (!compilerStack.hasError() || _inputsAndSettings.parserErrorRecovery))
if (parsingSuccess && !analysisFailed && (!compilerStack.hasError() || _inputsAndSettings.parserErrorRecovery))
for (string const& sourceName: compilerStack.sourceNames())
{
Json::Value sourceResult = Json::objectValue;

View File

@ -18,11 +18,5 @@
"type": "DeclarationError"
}
],
"sources":
{
"":
{
"id": 0
}
}
"sources": {}
}

View File

@ -22,106 +22,5 @@
"type": "DeclarationError"
}
],
"sources":
{
"C":
{
"ast":
{
"absolutePath": "C",
"exportedSymbols":
{
"f":
[
7
]
},
"id": 8,
"license": "GPL-3.0",
"nodeType": "SourceUnit",
"nodes":
[
{
"id": 1,
"literals":
[
"solidity",
"*"
],
"nodeType": "PragmaDirective",
"src": "36:18:0"
},
{
"body":
{
"id": 6,
"nodeType": "Block",
"src": "261:2:0",
"statements": []
},
"id": 7,
"implemented": true,
"kind": "freeFunction",
"modifiers": [],
"name": "f",
"nameLocation": "241:1:0",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 4,
"nodeType": "ParameterList",
"parameters":
[
{
"constant": false,
"id": 3,
"mutability": "immutable",
"name": "x",
"nameLocation": "258:1:0",
"nodeType": "VariableDeclaration",
"scope": 7,
"src": "243:16:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName":
{
"id": 2,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "243:4:0",
"typeDescriptions":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"visibility": "internal"
}
],
"src": "242:18:0"
},
"returnParameters":
{
"id": 5,
"nodeType": "ParameterList",
"parameters": [],
"src": "261:0:0"
},
"scope": 8,
"src": "232:31:0",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "internal"
}
],
"src": "36:228:0"
},
"id": 0
}
}
"sources": {}
}