Skip to content

Commit ddc9f0d

Browse files
authored
Merge pull request #15907 from ethereum/error-and-ice-reporting-tweaks
Error and ICE reporting tweaks
2 parents 1965d74 + c422fa5 commit ddc9f0d

File tree

17 files changed

+157
-24
lines changed

17 files changed

+157
-24
lines changed

Changelog.md

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Compiler Features:
1616

1717

1818
Bugfixes:
19+
* Commandline Interface: Report StackTooDeep errors in compiler mode as proper errors instead of printing diagnostic information meant for internal compiler errors.
20+
* Error Reporting: Fix error locations not being shown for source files with empty names.
1921
* General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts.
2022
* Metadata: Fix custom cleanup sequence missing from metadata when other optimizer settings have default values.
2123
* SMTChecker: Fix internal compiler error when analyzing overflowing expressions or bitwise negation of unsigned types involving constants.

liblangutil/SourceReferenceFormatter.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,11 @@ AnsiColorized SourceReferenceFormatter::diagColored() const
114114

115115
void SourceReferenceFormatter::printSourceLocation(SourceReference const& _ref)
116116
{
117-
if (_ref.sourceName.empty())
118-
return; // Nothing we can print here
119-
120117
if (_ref.position.line < 0)
121118
{
119+
if (_ref.sourceName.empty())
120+
return; // Nothing we can print here
121+
122122
frameColored() << "-->";
123123
m_stream << ' ' << _ref.sourceName << '\n';
124124
return; // No line available, nothing else to print

libsolidity/interface/CompilerStack.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,12 @@ YulStack CompilerStack::loadGeneratedIR(std::string const& _ir) const
827827
yulAnalysisSuccessful,
828828
_ir + "\n\n"
829829
"Invalid IR generated:\n" +
830-
SourceReferenceFormatter::formatErrorInformation(stack.errors(), stack) + "\n"
830+
SourceReferenceFormatter::formatErrorInformation(
831+
stack.errors(),
832+
stack, // _charStreamProvider
833+
false, // _colored
834+
true // _withErrorIds
835+
) + "\n"
831836
);
832837

833838
return stack;

libsolidity/interface/StandardCompiler.cpp

+22-14
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ Json formatErrorWithException(
131131
);
132132

133133
if (std::string const* description = _exception.comment())
134-
message = ((_message.length() > 0) ? (_message + ":") : "") + *description;
134+
message = ((_message.length() > 0) ? (_message + ": ") : "") + *description;
135135
else
136136
message = _message;
137137

@@ -1412,6 +1412,7 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu
14121412
));
14131413
}
14141414
}
1415+
// NOTE: This includes langutil::StackTooDeepError.
14151416
catch (CompilerError const& _exception)
14161417
{
14171418
errors.emplace_back(formatErrorWithException(
@@ -1422,39 +1423,43 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu
14221423
"Compiler error (" + _exception.lineInfo() + ")"
14231424
));
14241425
}
1425-
catch (InternalCompilerError const& _exception)
1426+
catch (yul::StackTooDeepError const& _exception)
14261427
{
14271428
errors.emplace_back(formatErrorWithException(
14281429
compilerStack,
14291430
_exception,
1431+
Error::Type::YulException,
1432+
"general",
1433+
"" // No prefix needed. These messages already say it's a "stack too deep" error.
1434+
));
1435+
}
1436+
catch (InternalCompilerError const&)
1437+
{
1438+
errors.emplace_back(formatError(
14301439
Error::Type::InternalCompilerError,
14311440
"general",
1432-
"Internal compiler error (" + _exception.lineInfo() + ")"
1441+
"Internal compiler error:\n" + boost::current_exception_diagnostic_information()
14331442
));
14341443
}
14351444
catch (UnimplementedFeatureError const& _exception)
14361445
{
14371446
// let StandardCompiler::compile handle this
14381447
throw _exception;
14391448
}
1440-
catch (yul::YulException const& _exception)
1449+
catch (YulAssertion const&)
14411450
{
1442-
errors.emplace_back(formatErrorWithException(
1443-
compilerStack,
1444-
_exception,
1451+
errors.emplace_back(formatError(
14451452
Error::Type::YulException,
14461453
"general",
1447-
"Yul exception"
1454+
"Yul assertion failed:\n" + boost::current_exception_diagnostic_information()
14481455
));
14491456
}
1450-
catch (smtutil::SMTLogicError const& _exception)
1457+
catch (smtutil::SMTLogicError const&)
14511458
{
1452-
errors.emplace_back(formatErrorWithException(
1453-
compilerStack,
1454-
_exception,
1459+
errors.emplace_back(formatError(
14551460
Error::Type::SMTLogicException,
14561461
"general",
1457-
"SMT logic exception"
1462+
"SMT logic error:\n" + boost::current_exception_diagnostic_information()
14581463
));
14591464
}
14601465
catch (...)
@@ -1827,7 +1832,10 @@ Json StandardCompiler::compile(Json const& _input) noexcept
18271832
}
18281833
catch (...)
18291834
{
1830-
return formatFatalError(Error::Type::InternalCompilerError, "Internal exception in StandardCompiler::compile: " + boost::current_exception_diagnostic_information());
1835+
return formatFatalError(
1836+
Error::Type::InternalCompilerError,
1837+
"Uncaught exception:\n" + boost::current_exception_diagnostic_information()
1838+
);
18311839
}
18321840
}
18331841

libyul/AsmAnalysis.cpp

+30-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,36 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(
113113
{},
114114
std::move(_objectStructure)
115115
).analyze(_astRoot);
116-
yulAssert(success && !errors.hasErrors(), "Invalid assembly/yul code.");
116+
117+
if (!success)
118+
{
119+
auto formatErrors = [](ErrorList const& _errorList) {
120+
std::vector<std::string> formattedErrors;
121+
for (std::shared_ptr<Error const> const& error: _errorList)
122+
{
123+
yulAssert(error->comment());
124+
formattedErrors.push_back(fmt::format(
125+
// Intentionally not showing source locations because we don't have the original
126+
// source here and it's unlikely they match the pretty-printed version.
127+
// They may not even match the original source if the AST was modified by the optimizer.
128+
"- {} {}: {}",
129+
Error::formatErrorType(error->type()),
130+
error->errorId().error,
131+
*error->comment()
132+
));
133+
}
134+
return joinHumanReadable(formattedErrors, "\n");
135+
};
136+
137+
yulAssert(errors.hasErrors(), "Yul analysis failed but did not report any errors.");
138+
yulAssert(false, fmt::format(
139+
"{}\n\nExpected valid Yul, but errors were reported during analysis:\n{}",
140+
AsmPrinter{_dialect}(_astRoot),
141+
formatErrors(errorList)
142+
));
143+
}
144+
145+
yulAssert(!errors.hasErrors());
117146
return analysisInfo;
118147
}
119148

libyul/Exceptions.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ namespace solidity::yul
3636
struct YulException: virtual util::Exception {};
3737
struct OptimizerException: virtual YulException {};
3838
struct CodegenException: virtual YulException {};
39-
struct YulAssertion: virtual YulException {};
39+
struct YulAssertion: virtual util::Exception {};
4040

4141
struct StackTooDeepError: virtual YulException
4242
{

solc/CommandLineInterface.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,7 @@ void CommandLineInterface::compile()
10091009
if (!successful)
10101010
solThrow(CommandLineExecutionError, "");
10111011
}
1012+
// NOTE: This includes langutil::StackTooDeepError.
10121013
catch (CompilerError const& _exception)
10131014
{
10141015
m_hasOutput = true;
@@ -1018,6 +1019,15 @@ void CommandLineInterface::compile()
10181019
);
10191020
solThrow(CommandLineExecutionError, "");
10201021
}
1022+
catch (yul::StackTooDeepError const& _exception)
1023+
{
1024+
m_hasOutput = true;
1025+
formatter.printExceptionInformation(
1026+
_exception,
1027+
Error::errorSeverity(Error::Type::YulException)
1028+
);
1029+
solThrow(CommandLineExecutionError, "");
1030+
}
10211031
}
10221032

10231033
void CommandLineInterface::handleCombinedJSON()

solc/main.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ int main(int argc, char** argv)
5151
std::cerr << boost::diagnostic_information(_exception);
5252
return 2;
5353
}
54+
catch (yul::YulAssertion const& _exception)
55+
{
56+
std::cerr << "Yul assertion failed:" << std::endl;
57+
std::cerr << boost::diagnostic_information(_exception);
58+
return 2;
59+
}
5460
catch (...)
5561
{
5662
std::cerr << "Uncaught exception:" << std::endl;

test/CommonSyntaxTest.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,15 @@ void CommonSyntaxTest::printErrorList(
197197
for (auto const& error: _errorList)
198198
{
199199
{
200-
util::AnsiColorized scope(
200+
util::AnsiColorized formattedStream(
201201
_stream,
202202
_formatted,
203203
{BOLD, SourceReferenceFormatter::errorTextColor(Error::errorSeverity(error.type))}
204204
);
205-
_stream << _linePrefix << Error::formatErrorType(error.type);
205+
formattedStream << _linePrefix << Error::formatErrorType(error.type);
206206
if (error.errorId.has_value())
207-
_stream << ' ' << error.errorId->error;
208-
_stream << ": ";
207+
formattedStream << ' ' << error.errorId->error;
208+
formattedStream << ": ";
209209
}
210210
if (!error.sourceName.empty() || error.locationStart >= 0 || error.locationEnd >= 0)
211211
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--via-ir --bin
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Error: Cannot swap Variable value23 with Slot 0x20: too deep in the stack by 9 slots in [ RET value23 value22 value21 value20 value19 value18 value17 value16 value15 value14 value13 value12 value11 value10 value9 value8 value7 value6 value5 value4 value3 value2 value1 value0 pos 0x20 ]
2+
memoryguard was present.
3+
--> stack_too_deep_from_code_transform/input.sol:1:1:
4+
|
5+
1 | contract C {
6+
| ^ (Relevant source part starts here and spans across multiple lines).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
contract C {
2+
function f() public {
3+
uint b;
4+
abi.encodePacked(
5+
b, b, b, b, b, b, b, b,
6+
b, b, b, b, b, b, b, b,
7+
b, b, b, b, b, b, b, b
8+
);
9+
}
10+
}

test/cmdlineTests/standard_empty_file_name/output.json

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
"component": "general",
55
"errorCode": "2904",
66
"formattedMessage": "DeclarationError: Declaration \"A\" not found in \"\" (referenced as \".\").
7+
--> :2:24:
8+
|
9+
2 | pragma solidity >=0.0; import {A} from \".\";
10+
| ^^^^^^^^^^^^^^^^^^^^
711

812
",
913
"message": "Declaration \"A\" not found in \"\" (referenced as \".\").",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
contract C {
2+
function f() public {
3+
uint b;
4+
abi.encodePacked(
5+
b, b, b, b, b, b, b, b,
6+
b, b, b, b, b, b, b, b,
7+
b, b, b, b, b, b, b, b
8+
);
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"language": "Solidity",
3+
"sources": {
4+
"in.sol": {"urls": ["standard_stack_too_deep_from_code_transform/in.sol"]}
5+
},
6+
"settings": {
7+
"viaIR": true,
8+
"outputSelection": {
9+
"*": {"*": ["evm.bytecode"]}
10+
}
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"errors": [
3+
{
4+
"component": "general",
5+
"formattedMessage": "YulException: Cannot swap Variable value23 with Slot 0x20: too deep in the stack by 9 slots in [ RET value23 value22 value21 value20 value19 value18 value17 value16 value15 value14 value13 value12 value11 value10 value9 value8 value7 value6 value5 value4 value3 value2 value1 value0 pos 0x20 ]
6+
memoryguard was present.
7+
--> in.sol:1:1:
8+
|
9+
1 | contract C {
10+
| ^ (Relevant source part starts here and spans across multiple lines).
11+
12+
",
13+
"message": "Cannot swap Variable value23 with Slot 0x20: too deep in the stack by 9 slots in [ RET value23 value22 value21 value20 value19 value18 value17 value16 value15 value14 value13 value12 value11 value10 value9 value8 value7 value6 value5 value4 value3 value2 value1 value0 pos 0x20 ]
14+
memoryguard was present.",
15+
"severity": "error",
16+
"sourceLocation": {
17+
"end": 206,
18+
"file": "in.sol",
19+
"start": 0
20+
},
21+
"type": "YulException"
22+
}
23+
],
24+
"sources": {
25+
"in.sol": {
26+
"id": 0
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)