Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions libsolidity/analysis/SyntaxChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma)
else if (_pragma.literals()[0] == "experimental")
{
solAssert(m_sourceUnit, "");
if (!m_experimental)
m_errorReporter.syntaxError(
2816_error,
_pragma.location(),
"Experimental pragmas can only be used if the experimental mode has been enabled."
);
std::vector<std::string> literals(_pragma.literals().begin() + 1, _pragma.literals().end());
if (literals.empty())
m_errorReporter.syntaxError(
Expand Down
10 changes: 8 additions & 2 deletions libsolidity/analysis/SyntaxChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,12 @@ class SyntaxChecker: private ASTConstVisitor
{
public:
/// @param _errorReporter provides the error logging functionality.
SyntaxChecker(langutil::ErrorReporter& _errorReporter, bool _useYulOptimizer):
/// @param _useYulOptimizer indicates whether Yul optimizer is enabled.
/// @param _experimental indicates whether the experimental toggle (option) is enabled.
SyntaxChecker(langutil::ErrorReporter& _errorReporter, bool _useYulOptimizer, bool _experimental):
m_errorReporter(_errorReporter),
m_useYulOptimizer(_useYulOptimizer)
m_useYulOptimizer(_useYulOptimizer),
m_experimental(_experimental)
{}

bool checkSyntax(ASTNode const& _astRoot);
Expand Down Expand Up @@ -112,6 +115,9 @@ class SyntaxChecker: private ASTConstVisitor
/// Flag that indicates whether we are inside an unchecked block.
bool m_uncheckedArithmetic = false;

/// Flag that indicates whether experimental mode is toggled.
bool m_experimental = false;

int m_inLoopDepth = 0;
std::optional<ContractKind> m_currentContractKind;

Expand Down
8 changes: 7 additions & 1 deletion libsolidity/interface/CompilerStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ void CompilerStack::setViaIR(bool _viaIR)
m_viaIR = _viaIR;
}

void CompilerStack::setExperimental(bool _experimental)
{
solAssert(m_stackState < ParsedAndImported, "Must set experimental before parsing.");
m_experimental = _experimental;
}

void CompilerStack::setEVMVersion(langutil::EVMVersion _version)
{
solAssert(m_stackState < ParsedAndImported, "Must set EVM version before parsing.");
Expand Down Expand Up @@ -467,7 +473,7 @@ bool CompilerStack::analyze()
{
bool experimentalSolidity = isExperimentalSolidity();

SyntaxChecker syntaxChecker(m_errorReporter, m_optimiserSettings.runYulOptimiser);
SyntaxChecker syntaxChecker(m_errorReporter, m_optimiserSettings.runYulOptimiser, m_experimental);
for (Source const* source: m_sourceOrder)
if (source->ast && !syntaxChecker.checkSyntax(*source->ast))
noErrors = false;
Expand Down
4 changes: 4 additions & 0 deletions libsolidity/interface/CompilerStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac
/// Must be set before parsing.
void setViaIR(bool _viaIR);

/// Sets the experimental toggle to allow usage of experimental features.
void setExperimental(bool _experimental);

/// Set the EVM version used before running compile.
/// When called without an argument it will revert to the default version.
/// Must be set before parsing.
Expand Down Expand Up @@ -607,6 +610,7 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac
RevertStrings m_revertStrings = RevertStrings::Default;
State m_stopAfter = State::CompilationSuccessful;
bool m_viaIR = false;
bool m_experimental = false;
langutil::EVMVersion m_evmVersion;
std::optional<uint8_t> m_eofVersion;
ModelCheckerSettings m_modelCheckerSettings;
Expand Down
4 changes: 2 additions & 2 deletions scripts/ASTImportTest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function test_ast_import_export_equivalence
local input_files=( "${@:2}" )

local export_command=("$SOLC" --combined-json ast --pretty-json --json-indent 4 "${input_files[@]}")
local import_command=("$SOLC" --import-ast --combined-json ast --pretty-json --json-indent 4 expected.json)
local import_command=("$SOLC" --experimental --import-ast --combined-json ast --pretty-json --json-indent 4 expected.json)
local import_via_standard_json_command=("$SOLC" --combined-json ast --pretty-json --json-indent 4 --standard-json standard_json_input.json)

# export ast - save ast json as expected result (silently)
Expand Down Expand Up @@ -228,7 +228,7 @@ function test_evmjson_import_export_equivalence
local bin_file_from_asm_import
bin_file_from_asm_import="import/$(basename "${asm_json_file}" .json).bin"

local import_options=(--bin --import-asm-json "${asm_json_file}")
local import_options=(--experimental --bin --import-asm-json "${asm_json_file}")
run_solc_store_stdout "${bin_file_from_asm_import}" "${import_options[@]}"

stripCLIDecorations < "$bin_file_from_asm_import" > tmpfile
Expand Down
1 change: 1 addition & 0 deletions solc/CommandLineInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,7 @@ void CommandLineInterface::compile()

try
{
m_compiler->setExperimental(m_options.experimental);
if (m_options.metadata.literalSources)
m_compiler->useMetadataLiteralSources(true);
m_compiler->setMetadataFormat(m_options.metadata.format);
Expand Down
54 changes: 54 additions & 0 deletions solc/CommandLineParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ static std::string const g_strEVMVersion = "evm-version";
static std::string const g_strEOFVersion = "experimental-eof-version";
static std::string const g_strViaIR = "via-ir";
static std::string const g_strExperimentalViaIR = "experimental-via-ir";
static std::string const g_strExperimental = "experimental";
static std::string const g_strGas = "gas";
static std::string const g_strHelp = "help";
static std::string const g_strImportAst = "import-ast";
Expand Down Expand Up @@ -157,6 +158,18 @@ void CommandLineParser::checkMutuallyExclusive(std::vector<std::string> const& _
}
}

void CommandLineParser::checkExperimental(std::vector<std::string> const& _optionNames)
{
if (!m_args.contains(g_strExperimental) && countEnabledOptions(_optionNames) > 0)
{
solThrow(
CommandLineValidationError,
"The following options are only available in experimental mode: " + joinOptionNames(_optionNames) + ". " +
"To toggle experimental mode, use the --experimental flag."
);
}
}

bool CompilerOutputs::operator==(CompilerOutputs const& _other) const noexcept
{
for (bool CompilerOutputs::* member: componentMap() | ranges::views::values)
Expand Down Expand Up @@ -936,6 +949,17 @@ General Information)").c_str(),
;
desc.add(smtCheckerOptions);

po::options_description experimentalOptions("Experimental options");
experimentalOptions.add_options()
(
g_strExperimental.c_str(),
"Toggle experimental mode. Note that toggling experimental mode by itself will not "
"enable any experimental features, but will simply allow for such features to be enabled in the "
"usual manner, whether by using specific flags or pragmas."
)
;
desc.add(experimentalOptions);

desc.add_options()(g_strInputFile.c_str(), po::value<std::vector<std::string>>(), "input file");
return desc;
}
Expand Down Expand Up @@ -979,6 +1003,9 @@ void CommandLineParser::processArgs()
else if (m_args.count(g_strColor) > 0)
m_options.formatting.coloredOutput = true;

if (m_args.contains(g_strExperimental))
m_options.experimental = true;

checkMutuallyExclusive({
g_strHelp,
g_strLicense,
Expand All @@ -992,6 +1019,18 @@ void CommandLineParser::processArgs()
g_strImportEvmAssemblerJson,
});

checkExperimental({
g_strLSP,
g_strImportAst,
g_strImportEvmAssemblerJson,
"ir-ast-json",
"ir-optimized-ast-json",
"yul-cfg-json",
"ethdebug",
"ethdebug-runtime",
g_strEOFVersion,
});

if (m_args.count(g_strHelp) > 0)
m_options.input.mode = InputMode::Help;
else if (m_args.count(g_strLicense) > 0)
Expand Down Expand Up @@ -1020,6 +1059,14 @@ void CommandLineParser::processArgs()
)
return;

if (m_options.experimental && m_options.input.mode == InputMode::StandardJson)
solThrow(
CommandLineValidationError,
"Standard JSON input mode is incompatible with the --" + g_strExperimental + " flag. "
"Please use the appropriate experimental option in your Standard JSON input file to "
"enable experimental mode."
);

if (m_args.count(g_strYul) > 0)
solThrow(
CommandLineValidationError,
Expand Down Expand Up @@ -1092,6 +1139,7 @@ void CommandLineParser::processArgs()
g_strPrettyJson,
"srcmap",
"srcmap-runtime",
g_strExperimental,
};

for (auto const& [optionName, optionValue]: m_args)
Expand Down Expand Up @@ -1159,6 +1207,12 @@ void CommandLineParser::processArgs()
if (!m_options.output.debugInfoSelection.has_value())
solThrow(CommandLineValidationError, "Invalid value for --" + g_strDebugInfo + " option: " + optionValue);

if (!m_options.experimental && m_options.output.debugInfoSelection->ethdebug)
solThrow(
CommandLineValidationError,
"--" + g_strDebugInfo + " ethdebug can only be used by toggling the --" + g_strExperimental + " flag."
);

if (m_options.output.debugInfoSelection->snippet && !m_options.output.debugInfoSelection->location)
solThrow(CommandLineValidationError, "To use 'snippet' with --" + g_strDebugInfo + " you must select also 'location'.");
}
Expand Down
3 changes: 3 additions & 0 deletions solc/CommandLineParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ struct CommandLineOptions
bool initialize = false;
ModelCheckerSettings settings;
} modelChecker;

bool experimental = false;
};

/// Parses the command-line arguments and produces a filled-out CommandLineOptions structure.
Expand Down Expand Up @@ -296,6 +298,7 @@ class CommandLineParser
void parseOutputSelection();

void checkMutuallyExclusive(std::vector<std::string> const& _optionNames);
void checkExperimental(std::vector<std::string> const& _optionNames);
size_t countEnabledOptions(std::vector<std::string> const& _optionNames) const;
static std::string joinOptionNames(std::vector<std::string> const& _optionNames, std::string _separator = ", ");

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--pretty-json --json-indent 4 --import-asm-json -
--pretty-json --json-indent 4 --experimental --import-asm-json -
2 changes: 1 addition & 1 deletion test/cmdlineTests/asm_json_yul_export_evm_asm_import/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm --bin --asm-json --pretty-json --json-indent 4
--experimental --import-asm-json - --opcodes --asm --bin --asm-json --pretty-json --json-indent 4
2 changes: 1 addition & 1 deletion test/cmdlineTests/ast_ir/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--ir-ast-json --ir-optimized-ast-json --optimize --pretty-json --json-indent 4
--experimental --ir-ast-json --ir-optimized-ast-json --optimize --pretty-json --json-indent 4
2 changes: 1 addition & 1 deletion test/cmdlineTests/ast_json_import_wrong_evmVersion/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--evm-version=homestead --import-ast --combined-json ast --pretty-json
--experimental --evm-version=homestead --import-ast --combined-json ast --pretty-json
2 changes: 1 addition & 1 deletion test/cmdlineTests/eof_unavailable_before_osaka/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--optimize --experimental-eof-version 1 --evm-version cancun
--experimental --optimize --experimental-eof-version 1 --evm-version cancun
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--debug-info ethdebug
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: --debug-info ethdebug can only be used by toggling the --experimental flag.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
pragma solidity >=0.0;

contract C {
function f() public {}
}
2 changes: 1 addition & 1 deletion test/cmdlineTests/ethdebug_eof_container_osaka/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--experimental-eof-version 1 --evm-version osaka --ethdebug --via-ir --pretty-json --json-indent 4
--experimental --experimental-eof-version 1 --evm-version osaka --ethdebug --via-ir --pretty-json --json-indent 4
2 changes: 1 addition & 1 deletion test/cmdlineTests/ethdebug_on_abstract/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--ethdebug --via-ir --pretty-json --json-indent 4
--experimental --ethdebug --via-ir --pretty-json --json-indent 4
2 changes: 1 addition & 1 deletion test/cmdlineTests/ethdebug_on_interface/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--ethdebug --via-ir --pretty-json --json-indent 4
--experimental --ethdebug --via-ir --pretty-json --json-indent 4
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--ir-ast-json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: The following options are only available in experimental mode: --lsp, --import-ast, --import-asm-json, --ir-ast-json, --ir-optimized-ast-json, --yul-cfg-json, --ethdebug, --ethdebug-runtime, --experimental-eof-version. To toggle experimental mode, use the --experimental flag.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
pragma solidity >=0.0;

contract C {
function f() public {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--experimental
1 change: 1 addition & 0 deletions test/cmdlineTests/experimental_flag_with_standard_json/err
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: Standard JSON input mode is incompatible with the --experimental flag. Please use the appropriate experimental option in your Standard JSON input file to enable experimental mode.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
Empty file.
2 changes: 1 addition & 1 deletion test/cmdlineTests/import_asm_json_all_valid_flags/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--pretty-json --json-indent 4 --combined-json bin,bin-runtime,opcodes,asm,srcmap,srcmap-runtime --asm --bin --bin-runtime --asm-json --import-asm-json -
--experimental --pretty-json --json-indent 4 --combined-json bin,bin-runtime,opcodes,asm,srcmap,srcmap-runtime --asm --bin --bin-runtime --asm-json --import-asm-json -
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm
--experimental --import-asm-json - --opcodes --asm
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json --experimental-eof-version 1 --evm-version cancun
--experimental --import-asm-json --experimental-eof-version 1 --evm-version cancun
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm
--experimental --import-asm-json - --opcodes --asm
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm
--experimental --import-asm-json - --opcodes --asm
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm
--experimental --import-asm-json - --opcodes --asm
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm
--experimental --import-asm-json - --opcodes --asm
2 changes: 1 addition & 1 deletion test/cmdlineTests/import_asm_json_invalid_value/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm
--experimental --import-asm-json - --opcodes --asm
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm
--experimental --import-asm-json - --opcodes --asm
2 changes: 1 addition & 1 deletion test/cmdlineTests/import_asm_json_no_optimize/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --asm
--experimental --import-asm-json - --asm
2 changes: 1 addition & 1 deletion test/cmdlineTests/import_asm_json_no_value/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm
--experimental --import-asm-json - --opcodes --asm
2 changes: 1 addition & 1 deletion test/cmdlineTests/import_asm_json_non_unique_sources/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--asm-json --import-asm-json -
--experimental --asm-json --import-asm-json -
2 changes: 1 addition & 1 deletion test/cmdlineTests/import_asm_json_optimize/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--optimize --import-asm-json - --asm
--experimental --optimize --import-asm-json - --asm
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm
--experimental --import-asm-json - --opcodes --asm
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm
--experimental --import-asm-json - --opcodes --asm
2 changes: 1 addition & 1 deletion test/cmdlineTests/import_asm_json_unrecognized_field/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm
--experimental --import-asm-json - --opcodes --asm
2 changes: 1 addition & 1 deletion test/cmdlineTests/import_asm_json_untagged_jumpdest/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm
--experimental --import-asm-json - --opcodes --asm
2 changes: 1 addition & 1 deletion test/cmdlineTests/import_asm_json_verbatim/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes --asm
--experimental --import-asm-json - --opcodes --asm
2 changes: 1 addition & 1 deletion test/cmdlineTests/import_asm_json_yul_more_subobjects/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes
--experimental --import-asm-json - --opcodes
2 changes: 1 addition & 1 deletion test/cmdlineTests/import_asm_json_yul_subobjects/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-asm-json - --opcodes
--experimental --import-asm-json - --opcodes
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--import-ast -
--experimental --import-ast -
2 changes: 1 addition & 1 deletion test/cmdlineTests/strict_asm_eof_container_osaka/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--strict-assembly --experimental-eof-version 1 --evm-version osaka --asm --ir-optimized --bin --debug-info none
--experimental --strict-assembly --experimental-eof-version 1 --evm-version osaka --asm --ir-optimized --bin --debug-info none
2 changes: 1 addition & 1 deletion test/cmdlineTests/strict_asm_eof_dataloadn_osaka/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--strict-assembly --experimental-eof-version 1 --evm-version osaka --asm --ir-optimized --bin --debug-info none
--experimental --strict-assembly --experimental-eof-version 1 --evm-version osaka --asm --ir-optimized --bin --debug-info none
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--strict-assembly --experimental-eof-version 1 --evm-version cancun
--experimental --strict-assembly --experimental-eof-version 1 --evm-version cancun
2 changes: 1 addition & 1 deletion test/cmdlineTests/strict_asm_yul_cfg_json_export/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--strict-assembly --optimize --yul-cfg-json --pretty-json --json-indent 4
--experimental --strict-assembly --optimize --yul-cfg-json --pretty-json --json-indent 4
2 changes: 1 addition & 1 deletion test/cmdlineTests/undeployable_contract_empty_outputs/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--bin --bin-runtime --opcodes --asm --ir --ir-ast-json --ir-optimized --ir-optimized-ast-json --gas --asm-json --abi --hashes --optimize --pretty-json --json-indent 4
--experimental --bin --bin-runtime --opcodes --asm --ir --ir-ast-json --ir-optimized --ir-optimized-ast-json --gas --asm-json --abi --hashes --optimize --pretty-json --json-indent 4
2 changes: 1 addition & 1 deletion test/cmdlineTests/yul_cfg_json_export/args
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--via-ir --optimize --yul-cfg-json --pretty-json --json-indent 4
--experimental --via-ir --optimize --yul-cfg-json --pretty-json --json-indent 4
2 changes: 1 addition & 1 deletion test/libsolidity/Assembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ evmasm::AssemblyItems compileContract(std::shared_ptr<CharStream> _sourceCode)
BOOST_CHECK(!!sourceUnit);

Scoper::assignScopes(*sourceUnit);
BOOST_REQUIRE(SyntaxChecker(errorReporter, false).checkSyntax(*sourceUnit));
BOOST_REQUIRE(SyntaxChecker(errorReporter, false, false).checkSyntax(*sourceUnit));
GlobalContext globalContext(solidity::test::CommonOptions::get().evmVersion());
NameAndTypeResolver resolver(globalContext, solidity::test::CommonOptions::get().evmVersion(), errorReporter, false);
DeclarationTypeChecker declarationTypeChecker(errorReporter, solidity::test::CommonOptions::get().evmVersion());
Expand Down
2 changes: 2 additions & 0 deletions test/libsolidity/FunctionDependencyGraphTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ TestCase::TestResult FunctionDependencyGraphTest::run(std::ostream& _stream, std
compiler().setSources(StringMap{{"", m_source}});
compiler().setViaIR(true);
compiler().setOptimiserSettings(OptimiserSettings::none());
// Experimental on by default as this is an extension of the initial experimental Solidity
compiler().setExperimental(true);
if (!compiler().compile(CompilerStack::AnalysisSuccessful))
{
printPrefixed(_stream, formatErrors(filteredErrors(), _formatted), _linePrefix);
Expand Down
2 changes: 0 additions & 2 deletions test/libsolidity/FunctionDependencyGraphTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@

#include <iosfwd>
#include <string>
#include <vector>
#include <utility>

namespace solidity::frontend::test
{
Expand Down
Loading