Skip to content

Commit

Permalink
Fix StandardCompiler returning an incomplete AST in Standard JSON in …
Browse files Browse the repository at this point in the history
…case of an early exit during analysis
  • Loading branch information
cameel committed Jun 15, 2023
1 parent f50820f commit 712229a
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 112 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
12 changes: 9 additions & 3 deletions libsolidity/interface/StandardCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
Expand All @@ -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;
Expand Down
8 changes: 1 addition & 7 deletions test/cmdlineTests/standard_empty_file_name/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,5 @@
"type": "DeclarationError"
}
],
"sources":
{
"":
{
"id": 0
}
}
"sources": {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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": {}
}

0 comments on commit 712229a

Please sign in to comment.