Skip to content

Commit b9b2c69

Browse files
committed
CommandLineParser: Validate compiler output selection
1 parent aed218f commit b9b2c69

File tree

17 files changed

+64
-21
lines changed

17 files changed

+64
-21
lines changed

Changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Compiler Features:
1010

1111
Bugfixes:
1212
* Commandline Interface: Fix extra newline character being appended to sources passed through standard input, affecting their hashes.
13+
* Commandline Interface: Report output selection options unsupported by the selected input mode instead of ignoring them.
1314
* SMTChecker: Fix internal error in magic type access (``block``, ``msg``, ``tx``).
1415
* TypeChecker: Fix internal error when using user defined value types in public library functions.
1516

solc/CommandLineParser.cpp

+51-2
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,14 @@ static set<string> const g_metadataHashArgs
137137
g_strNone
138138
};
139139

140+
static map<InputMode, string> const g_inputModeName = {
141+
{InputMode::Compiler, "compiler"},
142+
{InputMode::CompilerWithASTImport, "compiler (AST import)"},
143+
{InputMode::Assembler, "assembler"},
144+
{InputMode::StandardJson, "standard JSON"},
145+
{InputMode::Linker, "linker"},
146+
};
147+
140148
void CommandLineParser::printVersionAndExit()
141149
{
142150
sout() <<
@@ -460,6 +468,47 @@ bool CommandLineParser::parseLibraryOption(string const& _input)
460468
return true;
461469
}
462470

471+
bool CommandLineParser::parseOutputSelection()
472+
{
473+
static auto outputSupported = [](InputMode _mode, string_view _outputName)
474+
{
475+
static set<string> const compilerModeOutputs =
476+
CompilerOutputs::componentMap() |
477+
ranges::views::keys |
478+
ranges::to<set>();
479+
480+
switch (_mode)
481+
{
482+
case InputMode::Compiler:
483+
case InputMode::CompilerWithASTImport:
484+
return contains(compilerModeOutputs, _outputName);
485+
case InputMode::Assembler:
486+
case InputMode::StandardJson:
487+
case InputMode::Linker:
488+
return false;
489+
}
490+
491+
solAssert(false, "");
492+
};
493+
494+
for (auto&& [optionName, outputComponent]: CompilerOutputs::componentMap())
495+
m_options.compiler.outputs.*outputComponent = (m_args.count(optionName) > 0);
496+
497+
vector<string> unsupportedOutputs;
498+
for (auto&& [optionName, outputComponent]: CompilerOutputs::componentMap())
499+
if (m_options.compiler.outputs.*outputComponent && !outputSupported(m_options.input.mode, optionName))
500+
unsupportedOutputs.push_back(optionName);
501+
502+
if (!unsupportedOutputs.empty())
503+
{
504+
serr() << "The following outputs are not supported in " << g_inputModeName.at(m_options.input.mode) << " mode: ";
505+
serr() << joinOptionNames(unsupportedOutputs) << ".";
506+
return false;
507+
}
508+
509+
return true;
510+
}
511+
463512
po::options_description CommandLineParser::optionsDescription()
464513
{
465514
// Declare the supported options.
@@ -930,8 +979,8 @@ bool CommandLineParser::processArgs()
930979
m_options.formatting.json.indent = m_args[g_strJsonIndent].as<uint32_t>();
931980
}
932981

933-
for (auto&& [optionName, outputComponent]: CompilerOutputs::componentMap())
934-
m_options.compiler.outputs.*outputComponent = (m_args.count(optionName) > 0);
982+
if (!parseOutputSelection())
983+
return false;
935984

936985
m_options.compiler.estimateGas = (m_args.count(g_strGas) > 0);
937986

solc/CommandLineParser.h

+2
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ class CommandLineParser
286286
/// @return false if there are any validation errors, true otherwise.
287287
bool parseLibraryOption(std::string const& _input);
288288

289+
bool parseOutputSelection();
290+
289291
bool checkMutuallyExclusive(std::vector<std::string> const& _optionNames);
290292
[[noreturn]] void printVersionAndExit();
291293
[[noreturn]] void printLicenseAndExit();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--link --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --ewasm --hashes --userdoc --devdoc --metadata --storage-layout
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The following outputs are not supported in linker mode: --abi, --asm, --asm-json, --bin, --bin-runtime, --devdoc, --ewasm, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1

test/cmdlineTests/linker_mode_output_selection_invalid/input.bin

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--ast-compact-json --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --ewasm --hashes --userdoc --devdoc --metadata --storage-layout
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The following outputs are not supported in standard JSON mode: --abi, --asm, --asm-json, --ast-compact-json, --bin, --bin-runtime, --devdoc, --ewasm, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1

test/cmdlineTests/standard_cli_output_selection_invalid/input.json

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--strict-assembly --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --ewasm --hashes --userdoc --devdoc --metadata --storage-layout
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The following outputs are not supported in assembler mode: --abi, --asm, --asm-json, --bin, --bin-runtime, --devdoc, --ewasm, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1

test/cmdlineTests/strict_asm_output_selection_invalid/input.yul

Whitespace-only changes.
+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
--yul --yul-dialect evm --optimize --ir-optimized --optimize-runs 10000
1+
--yul --yul-dialect evm --optimize --optimize-runs 10000

test/solc/CommandLineParser.cpp

-18
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,6 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options)
289289
"underflow,"
290290
"divByZero",
291291
"--model-checker-timeout=5", // Ignored in assembly mode
292-
293-
// Accepted but has no effect in assembly mode
294-
"--ast-compact-json", "--asm", "--asm-json", "--opcodes", "--bin", "--bin-runtime", "--abi",
295-
"--ir", "--ir-optimized", "--ewasm", "--hashes", "--userdoc", "--devdoc", "--metadata", "--storage-layout",
296292
};
297293
commandLine += assemblyOptions;
298294
if (expectedLanguage == AssemblyStack::Language::StrictAssembly || expectedLanguage == AssemblyStack::Language::Ewasm)
@@ -328,11 +324,6 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options)
328324
};
329325
expectedOptions.formatting.coloredOutput = false;
330326
expectedOptions.formatting.withErrorIds = true;
331-
expectedOptions.compiler.outputs = {
332-
true, true, true, true, true,
333-
true, true, true, true, true,
334-
true, true, true, true, true,
335-
};
336327
if (expectedLanguage == AssemblyStack::Language::StrictAssembly || expectedLanguage == AssemblyStack::Language::Ewasm)
337328
{
338329
expectedOptions.optimizer.enabled = true;
@@ -388,10 +379,6 @@ BOOST_AUTO_TEST_CASE(standard_json_mode_options)
388379
"underflow,"
389380
"divByZero",
390381
"--model-checker-timeout=5", // Ignored in Standard JSON mode
391-
392-
// Accepted but has no effect in Standard JSON mode
393-
"--ast-compact-json", "--asm", "--asm-json", "--opcodes", "--bin", "--bin-runtime", "--abi",
394-
"--ir", "--ir-optimized", "--ewasm", "--hashes", "--userdoc", "--devdoc", "--metadata", "--storage-layout",
395382
};
396383

397384
CommandLineOptions expectedOptions;
@@ -408,11 +395,6 @@ BOOST_AUTO_TEST_CASE(standard_json_mode_options)
408395
expectedOptions.formatting.json = JsonFormat {JsonFormat::Pretty, 1};
409396
expectedOptions.formatting.coloredOutput = false;
410397
expectedOptions.formatting.withErrorIds = true;
411-
expectedOptions.compiler.outputs = {
412-
true, true, true, true, true,
413-
true, true, true, true, true,
414-
true, true, true, true, true,
415-
};
416398
expectedOptions.compiler.estimateGas = true;
417399
expectedOptions.compiler.combinedJsonRequests = CombinedJsonRequests{};
418400
expectedOptions.compiler.combinedJsonRequests->abi = true;

0 commit comments

Comments
 (0)