mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9812 from ethereum/develop
Merge develop into breaking.
This commit is contained in:
commit
39ecc18d4d
@ -8,9 +8,11 @@ Language Features:
|
||||
|
||||
|
||||
Compiler Features:
|
||||
* Export compiler-generated utility sources via standard-json or combined-json.
|
||||
* SMTChecker: Support ``revert()``.
|
||||
* SMTChecker: Support shifts.
|
||||
* SMTChecker: Support structs.
|
||||
* SMTChecker: Support ``type(T).min`` and ``type(T).max``.
|
||||
* SMTChecker: Support ``type(T).min``, ``type(T).max``, and ``type(I).interfaceId``.
|
||||
* Yul Optimizer: Prune unused parameters in functions.
|
||||
* Yul Optimizer: Inline into functions further down in the call graph first.
|
||||
* Yul Optimizer: Try to simplify function names.
|
||||
@ -18,6 +20,7 @@ Compiler Features:
|
||||
|
||||
Bugfixes:
|
||||
* Type Checker: Disallow ``virtual`` for modifiers in libraries.
|
||||
* Type Checker: Correct the warning for homonymous, but not shadowing declarations.
|
||||
* ViewPureChecker: Prevent visibility check on constructors.
|
||||
* Type system: Fix internal error on implicit conversion of contract instance to the type of its ``super``.
|
||||
* Type system: Fix named parameters in overloaded function and event calls being matched incorrectly if the order differs from the declaration.
|
||||
|
@ -503,11 +503,20 @@ bool DeclarationRegistrationHelper::registerDeclaration(
|
||||
else
|
||||
{
|
||||
auto shadowedLocation = shadowedDeclaration->location();
|
||||
_errorReporter.warning(
|
||||
2519_error,
|
||||
_declaration.location(),
|
||||
"This declaration shadows an existing declaration.",
|
||||
SecondarySourceLocation().append("The shadowed declaration is here:", shadowedLocation)
|
||||
|
||||
if (!shadowedDeclaration->isVisibleInContract())
|
||||
_errorReporter.warning(
|
||||
8760_error,
|
||||
_declaration.location(),
|
||||
"This declaration has the same name as another declaration.",
|
||||
SecondarySourceLocation().append("The other declaration is here:", shadowedLocation)
|
||||
);
|
||||
else
|
||||
_errorReporter.warning(
|
||||
2519_error,
|
||||
_declaration.location(),
|
||||
"This declaration shadows an existing declaration.",
|
||||
SecondarySourceLocation().append("The shadowed declaration is here:", shadowedLocation)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -208,6 +208,14 @@ vector<pair<util::FixedHash<4>, FunctionTypePointer>> const& ContractDefinition:
|
||||
});
|
||||
}
|
||||
|
||||
uint64_t ContractDefinition::interfaceId() const
|
||||
{
|
||||
uint64_t result{0};
|
||||
for (auto const& function: interfaceFunctionList(false))
|
||||
result ^= util::fromBigEndian<uint64_t>(function.first.ref());
|
||||
return result;
|
||||
}
|
||||
|
||||
TypePointer ContractDefinition::type() const
|
||||
{
|
||||
return TypeProvider::typeType(TypeProvider::contract(*this));
|
||||
|
@ -509,6 +509,8 @@ public:
|
||||
/// as intended for use by the ABI.
|
||||
std::map<util::FixedHash<4>, FunctionTypePointer> interfaceFunctions(bool _includeInheritedFunctions = true) const;
|
||||
std::vector<std::pair<util::FixedHash<4>, FunctionTypePointer>> const& interfaceFunctionList(bool _includeInheritedFunctions = true) const;
|
||||
/// @returns the EIP-165 compatible interface identifier. This will exclude inherited functions.
|
||||
uint64_t interfaceId() const;
|
||||
|
||||
/// @returns a list of all declarations in this contract
|
||||
std::vector<Declaration const*> declarations() const { return filteredNodes<Declaration>(m_subNodes); }
|
||||
|
@ -51,8 +51,8 @@ void Compiler::compileContract(
|
||||
|
||||
m_context.optimise(m_optimiserSettings);
|
||||
|
||||
solAssert(m_context.requestedYulFunctionsRan(), "requestedYulFunctions() was not called.");
|
||||
solAssert(m_runtimeContext.requestedYulFunctionsRan(), "requestedYulFunctions() was not called.");
|
||||
solAssert(m_context.appendYulUtilityFunctionsRan(), "appendYulUtilityFunctions() was not called.");
|
||||
solAssert(m_runtimeContext.appendYulUtilityFunctionsRan(), "appendYulUtilityFunctions() was not called.");
|
||||
}
|
||||
|
||||
std::shared_ptr<evmasm::Assembly> Compiler::runtimeAssemblyPtr() const
|
||||
|
@ -74,6 +74,9 @@ public:
|
||||
/// @returns Assembly items of the runtime compiler context
|
||||
evmasm::AssemblyItems const& runtimeAssemblyItems() const { return m_context.assembly().sub(m_runtimeSub).items(); }
|
||||
|
||||
std::string generatedYulUtilityCode() const { return m_context.generatedYulUtilityCode(); }
|
||||
std::string runtimeGeneratedYulUtilityCode() const { return m_runtimeContext.generatedYulUtilityCode(); }
|
||||
|
||||
/// @returns the entry label of the given function. Might return an AssemblyItem of type
|
||||
/// UndefinedItem if it does not exist yet.
|
||||
evmasm::AssemblyItem functionEntryLabel(FunctionDefinition const& _function) const;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <libsolidity/interface/Version.h>
|
||||
|
||||
#include <libyul/AsmParser.h>
|
||||
#include <libyul/AsmPrinter.h>
|
||||
#include <libyul/AsmAnalysis.h>
|
||||
#include <libyul/AsmAnalysisInfo.h>
|
||||
#include <libyul/backends/evm/AsmCodeGen.h>
|
||||
@ -37,6 +38,7 @@
|
||||
#include <libyul/optimiser/Suite.h>
|
||||
#include <libyul/Object.h>
|
||||
#include <libyul/YulString.h>
|
||||
#include <libyul/Utilities.h>
|
||||
|
||||
#include <libsolutil/Whiskers.h>
|
||||
|
||||
@ -51,9 +53,6 @@
|
||||
|
||||
// Change to "define" to output all intermediate code
|
||||
#undef SOL_OUTPUT_ASM
|
||||
#ifdef SOL_OUTPUT_ASM
|
||||
#include <libyul/AsmPrinter.h>
|
||||
#endif
|
||||
|
||||
|
||||
using namespace std;
|
||||
@ -191,14 +190,24 @@ void CompilerContext::appendMissingLowLevelFunctions()
|
||||
}
|
||||
}
|
||||
|
||||
pair<string, set<string>> CompilerContext::requestedYulFunctions()
|
||||
void CompilerContext::appendYulUtilityFunctions(OptimiserSettings const& _optimiserSettings)
|
||||
{
|
||||
solAssert(!m_requestedYulFunctionsRan, "requestedYulFunctions called more than once.");
|
||||
m_requestedYulFunctionsRan = true;
|
||||
solAssert(!m_appendYulUtilityFunctionsRan, "requestedYulFunctions called more than once.");
|
||||
m_appendYulUtilityFunctionsRan = true;
|
||||
|
||||
set<string> empty;
|
||||
swap(empty, m_externallyUsedYulFunctions);
|
||||
return {m_yulFunctionCollector.requestedFunctions(), std::move(empty)};
|
||||
string code = m_yulFunctionCollector.requestedFunctions();
|
||||
if (!code.empty())
|
||||
{
|
||||
appendInlineAssembly(
|
||||
yul::reindent("{\n" + move(code) + "\n}"),
|
||||
{},
|
||||
m_externallyUsedYulFunctions,
|
||||
true,
|
||||
_optimiserSettings,
|
||||
yulUtilityFileName()
|
||||
);
|
||||
solAssert(!m_generatedYulUtilityCode.empty(), "");
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerContext::addVariable(
|
||||
@ -369,7 +378,8 @@ void CompilerContext::appendInlineAssembly(
|
||||
vector<string> const& _localVariables,
|
||||
set<string> const& _externallyUsedFunctions,
|
||||
bool _system,
|
||||
OptimiserSettings const& _optimiserSettings
|
||||
OptimiserSettings const& _optimiserSettings,
|
||||
string _sourceName
|
||||
)
|
||||
{
|
||||
unsigned startStackHeight = stackHeight();
|
||||
@ -420,7 +430,7 @@ void CompilerContext::appendInlineAssembly(
|
||||
|
||||
ErrorList errors;
|
||||
ErrorReporter errorReporter(errors);
|
||||
auto scanner = make_shared<langutil::Scanner>(langutil::CharStream(_assembly, "--CODEGEN--"));
|
||||
auto scanner = make_shared<langutil::Scanner>(langutil::CharStream(_assembly, _sourceName));
|
||||
yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion);
|
||||
optional<langutil::SourceLocation> locationOverride;
|
||||
if (!_system)
|
||||
@ -469,6 +479,17 @@ void CompilerContext::appendInlineAssembly(
|
||||
|
||||
optimizeYul(obj, dialect, _optimiserSettings, externallyUsedIdentifiers);
|
||||
|
||||
if (_system)
|
||||
{
|
||||
// Store as generated sources, but first re-parse to update the source references.
|
||||
solAssert(m_generatedYulUtilityCode.empty(), "");
|
||||
m_generatedYulUtilityCode = yul::AsmPrinter(dialect)(*obj.code);
|
||||
string code = yul::AsmPrinter{dialect}(*obj.code);
|
||||
scanner = make_shared<langutil::Scanner>(langutil::CharStream(m_generatedYulUtilityCode, _sourceName));
|
||||
obj.code = yul::Parser(errorReporter, dialect).parse(scanner, false);
|
||||
*obj.analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj);
|
||||
}
|
||||
|
||||
analysisInfo = std::move(*obj.analysisInfo);
|
||||
parserResult = std::move(obj.code);
|
||||
|
||||
@ -477,6 +498,12 @@ void CompilerContext::appendInlineAssembly(
|
||||
cout << yul::AsmPrinter(&dialect)(*parserResult) << endl;
|
||||
#endif
|
||||
}
|
||||
else if (_system)
|
||||
{
|
||||
// Store as generated source.
|
||||
solAssert(m_generatedYulUtilityCode.empty(), "");
|
||||
m_generatedYulUtilityCode = _assembly;
|
||||
}
|
||||
|
||||
if (!errorReporter.errors().empty())
|
||||
reportError("Failed to analyze inline assembly block.");
|
||||
|
@ -163,12 +163,14 @@ public:
|
||||
void appendMissingLowLevelFunctions();
|
||||
ABIFunctions& abiFunctions() { return m_abiFunctions; }
|
||||
YulUtilFunctions& utilFunctions() { return m_yulUtilFunctions; }
|
||||
/// @returns concatenation of all generated functions and a set of the
|
||||
/// externally used functions.
|
||||
/// Clears the internal list, i.e. calling it again will result in an
|
||||
/// empty return value.
|
||||
std::pair<std::string, std::set<std::string>> requestedYulFunctions();
|
||||
bool requestedYulFunctionsRan() const { return m_requestedYulFunctionsRan; }
|
||||
|
||||
/// Appends concatenation of all generated Yul functions to the bytecode
|
||||
/// and stores the Yul source code to be returned by @a generatedYulUtilityCode.
|
||||
/// Should be called exactly once on each context.
|
||||
void appendYulUtilityFunctions(OptimiserSettings const& _optimiserSettings);
|
||||
bool appendYulUtilityFunctionsRan() const { return m_appendYulUtilityFunctionsRan; }
|
||||
std::string const& generatedYulUtilityCode() const { return m_generatedYulUtilityCode; }
|
||||
static std::string yulUtilityFileName() { return "#utility.yul"; }
|
||||
|
||||
/// Returns the distance of the given local variable from the bottom of the stack (of the current function).
|
||||
unsigned baseStackOffsetOfVariable(Declaration const& _declaration) const;
|
||||
@ -246,17 +248,21 @@ public:
|
||||
CompilerContext& operator<<(u256 const& _value) { m_asm->append(_value); return *this; }
|
||||
CompilerContext& operator<<(bytes const& _data) { m_asm->append(_data); return *this; }
|
||||
|
||||
/// Appends inline assembly (strict mode).
|
||||
/// @a _replacements are string-matching replacements that are performed prior to parsing the inline assembly.
|
||||
/// Appends inline assembly (strict-EVM dialect for the current version).
|
||||
/// @param _assembly the assembly text, should be a block.
|
||||
/// @param _localVariables assigns stack positions to variables with the last one being the stack top
|
||||
/// @param _externallyUsedFunctions a set of function names that are not to be renamed or removed.
|
||||
/// @param _system if true, this is a "system-level" assembly where all functions use named labels.
|
||||
/// @param _system if true, this is a "system-level" assembly where all functions use named labels
|
||||
/// and the code is marked to be exported as "compiler-generated assembly utility file".
|
||||
/// @param _optimiserSettings settings for the Yul optimiser, which is run in this function already.
|
||||
/// @param _sourceName the name of the assembly file to be used for source locations
|
||||
void appendInlineAssembly(
|
||||
std::string const& _assembly,
|
||||
std::vector<std::string> const& _localVariables = std::vector<std::string>(),
|
||||
std::set<std::string> const& _externallyUsedFunctions = std::set<std::string>(),
|
||||
bool _system = false,
|
||||
OptimiserSettings const& _optimiserSettings = OptimiserSettings::none()
|
||||
OptimiserSettings const& _optimiserSettings = OptimiserSettings::none(),
|
||||
std::string _sourceName = "--CODEGEN--"
|
||||
);
|
||||
|
||||
/// If m_revertStrings is debug, @returns inline assembly code that
|
||||
@ -385,14 +391,17 @@ private:
|
||||
MultiUseYulFunctionCollector m_yulFunctionCollector;
|
||||
/// Set of externally used yul functions.
|
||||
std::set<std::string> m_externallyUsedYulFunctions;
|
||||
/// Generated Yul code used as utility. Source references from the bytecode can point here.
|
||||
/// Produced from @a m_yulFunctionCollector.
|
||||
std::string m_generatedYulUtilityCode;
|
||||
/// Container for ABI functions to be generated.
|
||||
ABIFunctions m_abiFunctions;
|
||||
/// Container for Yul Util functions to be generated.
|
||||
YulUtilFunctions m_yulUtilFunctions;
|
||||
/// The queue of low-level functions to generate.
|
||||
std::queue<std::tuple<std::string, unsigned, unsigned, std::function<void(CompilerContext&)>>> m_lowLevelFunctionGenerationQueue;
|
||||
/// Flag to check that requestedYulFunctions() was called exactly once
|
||||
bool m_requestedYulFunctionsRan = false;
|
||||
/// Flag to check that appendYulUtilityFunctions() was called exactly once
|
||||
bool m_appendYulUtilityFunctionsRan = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1272,15 +1272,7 @@ void ContractCompiler::appendMissingFunctions()
|
||||
solAssert(m_context.nextFunctionToCompile() != function, "Compiled the wrong function?");
|
||||
}
|
||||
m_context.appendMissingLowLevelFunctions();
|
||||
auto [yulFunctions, externallyUsedYulFunctions] = m_context.requestedYulFunctions();
|
||||
if (!yulFunctions.empty())
|
||||
m_context.appendInlineAssembly(
|
||||
"{" + move(yulFunctions) + "}",
|
||||
{},
|
||||
externallyUsedYulFunctions,
|
||||
true,
|
||||
m_optimiserSettings
|
||||
);
|
||||
m_context.appendYulUtilityFunctions(m_optimiserSettings);
|
||||
}
|
||||
|
||||
void ContractCompiler::appendModifierOrFunctionCode()
|
||||
|
@ -143,6 +143,7 @@ private:
|
||||
/// Pointer to the runtime compiler in case this is a creation compiler.
|
||||
ContractCompiler* m_runtimeCompiler = nullptr;
|
||||
CompilerContext& m_context;
|
||||
|
||||
/// Tag to jump to for a "break" statement and the stack height after freeing the local loop variables.
|
||||
std::vector<std::pair<evmasm::AssemblyItem, unsigned>> m_breakTags;
|
||||
/// Tag to jump to for a "continue" statement and the stack height after freeing the local loop variables.
|
||||
|
@ -1598,10 +1598,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
||||
{
|
||||
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
|
||||
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();
|
||||
uint64_t result{0};
|
||||
for (auto const& function: contract.interfaceFunctionList(false))
|
||||
result ^= fromBigEndian<uint64_t>(function.first.ref());
|
||||
m_context << (u256{result} << (256 - 32));
|
||||
m_context << (u256{contract.interfaceId()} << (256 - 32));
|
||||
}
|
||||
else if (member == "min" || member == "max")
|
||||
{
|
||||
|
@ -1549,10 +1549,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||
{
|
||||
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
|
||||
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();
|
||||
uint64_t result{0};
|
||||
for (auto const& function: contract.interfaceFunctionList(false))
|
||||
result ^= fromBigEndian<uint64_t>(function.first.ref());
|
||||
define(_memberAccess) << formatNumber(u256{result} << (256 - 32)) << "\n";
|
||||
define(_memberAccess) << formatNumber(u256{contract.interfaceId()} << (256 - 32)) << "\n";
|
||||
}
|
||||
else if (member == "min" || member == "max")
|
||||
{
|
||||
|
@ -631,6 +631,10 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall)
|
||||
case FunctionType::Kind::Require:
|
||||
visitRequire(_funCall);
|
||||
break;
|
||||
case FunctionType::Kind::Revert:
|
||||
// Revert is a special case of require and equals to `require(false)`
|
||||
addPathImpliedExpression(smtutil::Expression(false));
|
||||
break;
|
||||
case FunctionType::Kind::GasLeft:
|
||||
visitGasLeft(_funCall);
|
||||
break;
|
||||
@ -888,6 +892,11 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess)
|
||||
IntegerType const& integerType = dynamic_cast<IntegerType const&>(*magicType->typeArgument());
|
||||
defineExpr(_memberAccess, memberName == "min" ? integerType.minValue() : integerType.maxValue());
|
||||
}
|
||||
else if (memberName == "interfaceId")
|
||||
{
|
||||
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*magicType->typeArgument()).contractDefinition();
|
||||
defineExpr(_memberAccess, contract.interfaceId());
|
||||
}
|
||||
else
|
||||
// NOTE: supporting name, creationCode, runtimeCode would be easy enough, but the bytes/string they return are not
|
||||
// at all useable in the SMT checker currently
|
||||
|
@ -57,7 +57,9 @@
|
||||
|
||||
#include <libyul/YulString.h>
|
||||
#include <libyul/AsmPrinter.h>
|
||||
#include <libyul/AsmJsonConverter.h>
|
||||
#include <libyul/AssemblyStack.h>
|
||||
#include <libyul/AsmParser.h>
|
||||
|
||||
#include <liblangutil/Scanner.h>
|
||||
#include <liblangutil/SemVerHandler.h>
|
||||
@ -591,6 +593,48 @@ evmasm::AssemblyItems const* CompilerStack::runtimeAssemblyItems(string const& _
|
||||
return currentContract.compiler ? &contract(_contractName).compiler->runtimeAssemblyItems() : nullptr;
|
||||
}
|
||||
|
||||
Json::Value CompilerStack::generatedSources(string const& _contractName, bool _runtime) const
|
||||
{
|
||||
if (m_stackState != CompilationSuccessful)
|
||||
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Compilation was not successful."));
|
||||
|
||||
Contract const& c = contract(_contractName);
|
||||
util::LazyInit<Json::Value const> const& sources =
|
||||
_runtime ?
|
||||
c.runtimeGeneratedSources :
|
||||
c.generatedSources;
|
||||
return sources.init([&]{
|
||||
Json::Value sources{Json::arrayValue};
|
||||
// If there is no compiler, then no bytecode was generated and thus no
|
||||
// sources were generated.
|
||||
if (c.compiler)
|
||||
{
|
||||
string source =
|
||||
_runtime ?
|
||||
c.compiler->runtimeGeneratedYulUtilityCode() :
|
||||
c.compiler->generatedYulUtilityCode();
|
||||
if (!source.empty())
|
||||
{
|
||||
string sourceName = CompilerContext::yulUtilityFileName();
|
||||
unsigned sourceIndex = sourceIndices()[sourceName];
|
||||
ErrorList errors;
|
||||
ErrorReporter errorReporter(errors);
|
||||
auto scanner = make_shared<langutil::Scanner>(langutil::CharStream(source, sourceName));
|
||||
yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion);
|
||||
shared_ptr<yul::Block> parserResult = yul::Parser{errorReporter, dialect}.parse(scanner, false);
|
||||
solAssert(parserResult, "");
|
||||
sources[0]["ast"] = yul::AsmJsonConverter{sourceIndex}(*parserResult);
|
||||
sources[0]["name"] = sourceName;
|
||||
sources[0]["id"] = sourceIndex;
|
||||
sources[0]["language"] = "Yul";
|
||||
sources[0]["contents"] = move(source);
|
||||
|
||||
}
|
||||
}
|
||||
return sources;
|
||||
});
|
||||
}
|
||||
|
||||
string const* CompilerStack::sourceMapping(string const& _contractName) const
|
||||
{
|
||||
if (m_stackState != CompilationSuccessful)
|
||||
@ -733,6 +777,8 @@ map<string, unsigned> CompilerStack::sourceIndices() const
|
||||
unsigned index = 0;
|
||||
for (auto const& s: m_sources)
|
||||
indices[s.first] = index++;
|
||||
solAssert(!indices.count(CompilerContext::yulUtilityFileName()), "");
|
||||
indices[CompilerContext::yulUtilityFileName()] = index++;
|
||||
return indices;
|
||||
}
|
||||
|
||||
|
@ -277,6 +277,10 @@ public:
|
||||
/// @returns runtime contract assembly items
|
||||
evmasm::AssemblyItems const* runtimeAssemblyItems(std::string const& _contractName) const;
|
||||
|
||||
/// @returns an array containing all utility sources generated during compilation.
|
||||
/// Format: [ { name: string, id: number, language: "Yul", contents: string }, ... ]
|
||||
Json::Value generatedSources(std::string const& _contractName, bool _runtime = false) const;
|
||||
|
||||
/// @returns the string that provides a mapping between bytecode and sourcecode or a nullptr
|
||||
/// if the contract does not (yet) have bytecode.
|
||||
std::string const* sourceMapping(std::string const& _contractName) const;
|
||||
@ -356,6 +360,8 @@ private:
|
||||
util::LazyInit<Json::Value const> storageLayout;
|
||||
util::LazyInit<Json::Value const> userDocumentation;
|
||||
util::LazyInit<Json::Value const> devDocumentation;
|
||||
util::LazyInit<Json::Value const> generatedSources;
|
||||
util::LazyInit<Json::Value const> runtimeGeneratedSources;
|
||||
mutable std::optional<std::string const> sourceMapping;
|
||||
mutable std::optional<std::string const> runtimeSourceMapping;
|
||||
};
|
||||
|
@ -230,6 +230,16 @@ bool isArtifactRequested(Json::Value const& _outputSelection, string const& _fil
|
||||
return false;
|
||||
}
|
||||
|
||||
/// @returns all artifact names of the EVM object, either for creation or deploy time.
|
||||
vector<string> evmObjectComponents(string const& _objectKind)
|
||||
{
|
||||
solAssert(_objectKind == "bytecode" || _objectKind == "deployedBytecode", "");
|
||||
vector<string> components{"", ".object", ".opcodes", ".sourceMap", ".generatedSources", ".linkReferences"};
|
||||
if (_objectKind == "deployedBytecode")
|
||||
components.push_back(".immutableReferences");
|
||||
return util::applyMap(components, [&](auto const& _s) { return "evm." + _objectKind + _s; });
|
||||
}
|
||||
|
||||
/// @returns true if any binary was requested, i.e. we actually have to perform compilation.
|
||||
bool isBinaryRequested(Json::Value const& _outputSelection)
|
||||
{
|
||||
@ -237,17 +247,12 @@ bool isBinaryRequested(Json::Value const& _outputSelection)
|
||||
return false;
|
||||
|
||||
// This does not include "evm.methodIdentifiers" on purpose!
|
||||
static vector<string> const outputsThatRequireBinaries{
|
||||
static vector<string> const outputsThatRequireBinaries = vector<string>{
|
||||
"*",
|
||||
"ir", "irOptimized",
|
||||
"wast", "wasm", "ewasm.wast", "ewasm.wasm",
|
||||
"evm.deployedBytecode", "evm.deployedBytecode.object", "evm.deployedBytecode.opcodes",
|
||||
"evm.deployedBytecode.sourceMap", "evm.deployedBytecode.linkReferences",
|
||||
"evm.deployedBytecode.immutableReferences",
|
||||
"evm.bytecode", "evm.bytecode.object", "evm.bytecode.opcodes", "evm.bytecode.sourceMap",
|
||||
"evm.bytecode.linkReferences",
|
||||
"evm.gasEstimates", "evm.legacyAssembly", "evm.assembly"
|
||||
};
|
||||
} + evmObjectComponents("bytecode") + evmObjectComponents("deployedBytecode");
|
||||
|
||||
for (auto const& fileRequests: _outputSelection)
|
||||
for (auto const& requests: fileRequests)
|
||||
@ -263,15 +268,10 @@ bool isEvmBytecodeRequested(Json::Value const& _outputSelection)
|
||||
if (!_outputSelection.isObject())
|
||||
return false;
|
||||
|
||||
static vector<string> const outputsThatRequireEvmBinaries{
|
||||
static vector<string> const outputsThatRequireEvmBinaries = vector<string>{
|
||||
"*",
|
||||
"evm.deployedBytecode", "evm.deployedBytecode.object", "evm.deployedBytecode.opcodes",
|
||||
"evm.deployedBytecode.sourceMap", "evm.deployedBytecode.linkReferences",
|
||||
"evm.deployedBytecode.immutableReferences",
|
||||
"evm.bytecode", "evm.bytecode.object", "evm.bytecode.opcodes", "evm.bytecode.sourceMap",
|
||||
"evm.bytecode.linkReferences",
|
||||
"evm.gasEstimates", "evm.legacyAssembly", "evm.assembly"
|
||||
};
|
||||
} + evmObjectComponents("bytecode") + evmObjectComponents("deployedBytecode");
|
||||
|
||||
for (auto const& fileRequests: _outputSelection)
|
||||
for (auto const& requests: fileRequests)
|
||||
@ -364,7 +364,12 @@ Json::Value formatImmutableReferences(map<u256, pair<string, vector<size_t>>> co
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value collectEVMObject(evmasm::LinkerObject const& _object, string const* _sourceMap, bool _runtimeObject)
|
||||
Json::Value collectEVMObject(
|
||||
evmasm::LinkerObject const& _object,
|
||||
string const* _sourceMap,
|
||||
Json::Value _generatedSources,
|
||||
bool _runtimeObject
|
||||
)
|
||||
{
|
||||
Json::Value output = Json::objectValue;
|
||||
output["object"] = _object.toHex();
|
||||
@ -373,6 +378,7 @@ Json::Value collectEVMObject(evmasm::LinkerObject const& _object, string const*
|
||||
output["linkReferences"] = formatLinkReferences(_object.linkReferences);
|
||||
if (_runtimeObject)
|
||||
output["immutableReferences"] = formatImmutableReferences(_object.immutableReferences);
|
||||
output["generatedSources"] = move(_generatedSources);
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -1074,12 +1080,13 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
_inputsAndSettings.outputSelection,
|
||||
file,
|
||||
name,
|
||||
{ "evm.bytecode", "evm.bytecode.object", "evm.bytecode.opcodes", "evm.bytecode.sourceMap", "evm.bytecode.linkReferences" },
|
||||
evmObjectComponents("bytecode"),
|
||||
wildcardMatchesExperimental
|
||||
))
|
||||
evmData["bytecode"] = collectEVMObject(
|
||||
compilerStack.object(contractName),
|
||||
compilerStack.sourceMapping(contractName),
|
||||
compilerStack.generatedSources(contractName),
|
||||
false
|
||||
);
|
||||
|
||||
@ -1087,12 +1094,13 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
_inputsAndSettings.outputSelection,
|
||||
file,
|
||||
name,
|
||||
{ "evm.deployedBytecode", "evm.deployedBytecode.object", "evm.deployedBytecode.opcodes", "evm.deployedBytecode.sourceMap", "evm.deployedBytecode.linkReferences", "evm.deployedBytecode.immutableReferences" },
|
||||
evmObjectComponents("deployedBytecode"),
|
||||
wildcardMatchesExperimental
|
||||
))
|
||||
evmData["deployedBytecode"] = collectEVMObject(
|
||||
compilerStack.runtimeObject(contractName),
|
||||
compilerStack.runtimeSourceMapping(contractName),
|
||||
compilerStack.generatedSources(contractName, true),
|
||||
true
|
||||
);
|
||||
|
||||
@ -1176,24 +1184,19 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
|
||||
tie(object, runtimeObject) = stack.assembleAndGuessRuntime();
|
||||
|
||||
for (string const& objectKind: vector<string>{"bytecode", "deployedBytecode"})
|
||||
{
|
||||
auto artifacts = util::applyMap(
|
||||
vector<string>{"", ".object", ".opcodes", ".sourceMap", ".linkReferences"},
|
||||
[&](auto const& _s) { return "evm." + objectKind + _s; }
|
||||
);
|
||||
if (isArtifactRequested(
|
||||
_inputsAndSettings.outputSelection,
|
||||
sourceName,
|
||||
contractName,
|
||||
artifacts,
|
||||
evmObjectComponents(objectKind),
|
||||
wildcardMatchesExperimental
|
||||
))
|
||||
{
|
||||
MachineAssemblyObject const& o = objectKind == "bytecode" ? object : runtimeObject;
|
||||
if (o.bytecode)
|
||||
output["contracts"][sourceName][contractName]["evm"][objectKind] = collectEVMObject(*o.bytecode, o.sourceMappings.get(), false);
|
||||
output["contracts"][sourceName][contractName]["evm"][objectKind] =
|
||||
collectEVMObject(*o.bytecode, o.sourceMappings.get(), Json::arrayValue, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "irOptimized", wildcardMatchesExperimental))
|
||||
output["contracts"][sourceName][contractName]["irOptimized"] = stack.print();
|
||||
|
@ -25,9 +25,9 @@ set -ev
|
||||
keyid=70D110489D66E2F6
|
||||
email=builds@ethereum.org
|
||||
packagename=libz3-static-dev
|
||||
version=4.8.8
|
||||
version=4.8.9
|
||||
|
||||
DISTRIBUTIONS="bionic eoan focal"
|
||||
DISTRIBUTIONS="bionic focal groovy"
|
||||
|
||||
for distribution in $DISTRIBUTIONS
|
||||
do
|
||||
@ -80,7 +80,9 @@ Vcs-Browser: https://github.com/Z3Prover/z3
|
||||
|
||||
Package: libz3-static-dev
|
||||
Section: libdevel
|
||||
Architecture: any-i386 any-amd64
|
||||
Architecture: any-amd64
|
||||
Breaks: libz3-dev
|
||||
Replaces: libz3-dev
|
||||
Multi-Arch: same
|
||||
Depends: \${shlibs:Depends}, \${misc:Depends}
|
||||
Description: theorem prover from Microsoft Research - development files (static library)
|
||||
|
@ -127,6 +127,8 @@ static string const g_strEVM = "evm";
|
||||
static string const g_strEVM15 = "evm15";
|
||||
static string const g_strEVMVersion = "evm-version";
|
||||
static string const g_strEwasm = "ewasm";
|
||||
static string const g_strGeneratedSources = "generated-sources";
|
||||
static string const g_strGeneratedSourcesRuntime = "generated-sources-runtime";
|
||||
static string const g_strGas = "gas";
|
||||
static string const g_strHelp = "help";
|
||||
static string const g_strImportAst = "import-ast";
|
||||
@ -238,6 +240,8 @@ static set<string> const g_combinedJsonArgs
|
||||
g_strBinary,
|
||||
g_strBinaryRuntime,
|
||||
g_strCompactJSON,
|
||||
g_strGeneratedSources,
|
||||
g_strGeneratedSourcesRuntime,
|
||||
g_strInterface,
|
||||
g_strMetadata,
|
||||
g_strNatspecUser,
|
||||
@ -1523,6 +1527,10 @@ void CommandLineInterface::handleCombinedJSON()
|
||||
contractData[g_strAsm] = m_compiler->assemblyJSON(contractName);
|
||||
if (requests.count(g_strStorageLayout) && m_compiler->compilationSuccessful())
|
||||
contractData[g_strStorageLayout] = jsonCompactPrint(m_compiler->storageLayout(contractName));
|
||||
if (requests.count(g_strGeneratedSources) && m_compiler->compilationSuccessful())
|
||||
contractData[g_strGeneratedSources] = m_compiler->generatedSources(contractName, false);
|
||||
if (requests.count(g_strGeneratedSourcesRuntime) && m_compiler->compilationSuccessful())
|
||||
contractData[g_strGeneratedSourcesRuntime] = m_compiler->generatedSources(contractName, true);
|
||||
if (requests.count(g_strSrcMap) && m_compiler->compilationSuccessful())
|
||||
{
|
||||
auto map = m_compiler->sourceMapping(contractName);
|
||||
|
@ -124,6 +124,7 @@ function test_solc_behaviour()
|
||||
sed -i.bak -e '/^Warning (3805): This is a pre-release compiler version, please do not use it in production./d' "$stderr_path"
|
||||
sed -i.bak -e 's/\(^[ ]*auxdata: \)0x[0-9a-f]*$/\1AUXDATA REMOVED/' "$stdout_path"
|
||||
sed -i.bak -e 's/ Consider adding "pragma .*$//' "$stderr_path"
|
||||
sed -i.bak -e 's/"version": "[^"]*"/"version": "VERSION REMOVED"/' "$stdout_path"
|
||||
# Remove trailing empty lines. Needs a line break to make OSX sed happy.
|
||||
sed -i.bak -e '1{/^$/d
|
||||
}' "$stderr_path"
|
||||
|
1
test/cmdlineTests/combined_json_generated_sources/args
Normal file
1
test/cmdlineTests/combined_json_generated_sources/args
Normal file
@ -0,0 +1 @@
|
||||
--combined-json generated-sources,generated-sources-runtime --pretty-json
|
5
test/cmdlineTests/combined_json_generated_sources/err
Normal file
5
test/cmdlineTests/combined_json_generated_sources/err
Normal file
@ -0,0 +1,5 @@
|
||||
Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.
|
||||
--> combined_json_generated_sources/input.sol
|
||||
|
||||
Warning: Source file does not specify required compiler version!
|
||||
--> combined_json_generated_sources/input.sol
|
1
test/cmdlineTests/combined_json_generated_sources/exit
Normal file
1
test/cmdlineTests/combined_json_generated_sources/exit
Normal file
@ -0,0 +1 @@
|
||||
0
|
@ -0,0 +1,5 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f(uint[] calldata) pure external {}
|
||||
}
|
735
test/cmdlineTests/combined_json_generated_sources/output
Normal file
735
test/cmdlineTests/combined_json_generated_sources/output
Normal file
@ -0,0 +1,735 @@
|
||||
{
|
||||
"contracts":
|
||||
{
|
||||
"combined_json_generated_sources/input.sol:C":
|
||||
{
|
||||
"generated-sources": [],
|
||||
"generated-sources-runtime":
|
||||
[
|
||||
{
|
||||
"ast":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "0:823:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "114:277:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "163:16:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"expression":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "172:1:1",
|
||||
"type": "",
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "175:1:1",
|
||||
"type": "",
|
||||
"value": "0"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "revert",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "165:6:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "165:12:1"
|
||||
},
|
||||
"nodeType": "YulExpressionStatement",
|
||||
"src": "165:12:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condition":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"name": "offset",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "142:6:1"
|
||||
},
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "150:4:1",
|
||||
"type": "",
|
||||
"value": "0x1f"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "add",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "138:3:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "138:17:1"
|
||||
},
|
||||
{
|
||||
"name": "end",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "157:3:1"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "slt",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "134:3:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "134:27:1"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "iszero",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "127:6:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "127:35:1"
|
||||
},
|
||||
"nodeType": "YulIf",
|
||||
"src": "124:2:1"
|
||||
},
|
||||
{
|
||||
"nodeType": "YulAssignment",
|
||||
"src": "188:30:1",
|
||||
"value":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"name": "offset",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "211:6:1"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "calldataload",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "198:12:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "198:20:1"
|
||||
},
|
||||
"variableNames":
|
||||
[
|
||||
{
|
||||
"name": "length",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "188:6:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "261:16:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"expression":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "270:1:1",
|
||||
"type": "",
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "273:1:1",
|
||||
"type": "",
|
||||
"value": "0"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "revert",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "263:6:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "263:12:1"
|
||||
},
|
||||
"nodeType": "YulExpressionStatement",
|
||||
"src": "263:12:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condition":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"name": "length",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "233:6:1"
|
||||
},
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "241:18:1",
|
||||
"type": "",
|
||||
"value": "0xffffffffffffffff"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "gt",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "230:2:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "230:30:1"
|
||||
},
|
||||
"nodeType": "YulIf",
|
||||
"src": "227:2:1"
|
||||
},
|
||||
{
|
||||
"nodeType": "YulAssignment",
|
||||
"src": "286:29:1",
|
||||
"value":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"name": "offset",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "302:6:1"
|
||||
},
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "310:4:1",
|
||||
"type": "",
|
||||
"value": "0x20"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "add",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "298:3:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "298:17:1"
|
||||
},
|
||||
"variableNames":
|
||||
[
|
||||
{
|
||||
"name": "arrayPos",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "286:8:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "369:16:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"expression":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "378:1:1",
|
||||
"type": "",
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "381:1:1",
|
||||
"type": "",
|
||||
"value": "0"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "revert",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "371:6:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "371:12:1"
|
||||
},
|
||||
"nodeType": "YulExpressionStatement",
|
||||
"src": "371:12:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condition":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"name": "arrayPos",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "334:8:1"
|
||||
},
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"name": "length",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "348:6:1"
|
||||
},
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "356:4:1",
|
||||
"type": "",
|
||||
"value": "0x20"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "mul",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "344:3:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "344:17:1"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "add",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "330:3:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "330:32:1"
|
||||
},
|
||||
{
|
||||
"name": "end",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "364:3:1"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "gt",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "327:2:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "327:41:1"
|
||||
},
|
||||
"nodeType": "YulIf",
|
||||
"src": "324:2:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "abi_decode_t_array$_t_uint256_$dyn_calldata_ptr",
|
||||
"nodeType": "YulFunctionDefinition",
|
||||
"parameters":
|
||||
[
|
||||
{
|
||||
"name": "offset",
|
||||
"nodeType": "YulTypedName",
|
||||
"src": "81:6:1",
|
||||
"type": ""
|
||||
},
|
||||
{
|
||||
"name": "end",
|
||||
"nodeType": "YulTypedName",
|
||||
"src": "89:3:1",
|
||||
"type": ""
|
||||
}
|
||||
],
|
||||
"returnVariables":
|
||||
[
|
||||
{
|
||||
"name": "arrayPos",
|
||||
"nodeType": "YulTypedName",
|
||||
"src": "97:8:1",
|
||||
"type": ""
|
||||
},
|
||||
{
|
||||
"name": "length",
|
||||
"nodeType": "YulTypedName",
|
||||
"src": "107:6:1",
|
||||
"type": ""
|
||||
}
|
||||
],
|
||||
"src": "24:367:1"
|
||||
},
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "498:322:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "544:16:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"expression":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "553:1:1",
|
||||
"type": "",
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "556:1:1",
|
||||
"type": "",
|
||||
"value": "0"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "revert",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "546:6:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "546:12:1"
|
||||
},
|
||||
"nodeType": "YulExpressionStatement",
|
||||
"src": "546:12:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condition":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"name": "dataEnd",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "519:7:1"
|
||||
},
|
||||
{
|
||||
"name": "headStart",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "528:9:1"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "sub",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "515:3:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "515:23:1"
|
||||
},
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "540:2:1",
|
||||
"type": "",
|
||||
"value": "32"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "slt",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "511:3:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "511:32:1"
|
||||
},
|
||||
"nodeType": "YulIf",
|
||||
"src": "508:2:1"
|
||||
},
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "570:243:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"nodeType": "YulVariableDeclaration",
|
||||
"src": "584:45:1",
|
||||
"value":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"name": "headStart",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "615:9:1"
|
||||
},
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "626:1:1",
|
||||
"type": "",
|
||||
"value": "0"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "add",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "611:3:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "611:17:1"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "calldataload",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "598:12:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "598:31:1"
|
||||
},
|
||||
"variables":
|
||||
[
|
||||
{
|
||||
"name": "offset",
|
||||
"nodeType": "YulTypedName",
|
||||
"src": "588:6:1",
|
||||
"type": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "676:16:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"expression":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "685:1:1",
|
||||
"type": "",
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "688:1:1",
|
||||
"type": "",
|
||||
"value": "0"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "revert",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "678:6:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "678:12:1"
|
||||
},
|
||||
"nodeType": "YulExpressionStatement",
|
||||
"src": "678:12:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"condition":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"name": "offset",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "648:6:1"
|
||||
},
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "656:18:1",
|
||||
"type": "",
|
||||
"value": "0xffffffffffffffff"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "gt",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "645:2:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "645:30:1"
|
||||
},
|
||||
"nodeType": "YulIf",
|
||||
"src": "642:2:1"
|
||||
},
|
||||
{
|
||||
"nodeType": "YulAssignment",
|
||||
"src": "705:98:1",
|
||||
"value":
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"arguments":
|
||||
[
|
||||
{
|
||||
"name": "headStart",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "775:9:1"
|
||||
},
|
||||
{
|
||||
"name": "offset",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "786:6:1"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "add",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "771:3:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "771:22:1"
|
||||
},
|
||||
{
|
||||
"name": "dataEnd",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "795:7:1"
|
||||
}
|
||||
],
|
||||
"functionName":
|
||||
{
|
||||
"name": "abi_decode_t_array$_t_uint256_$dyn_calldata_ptr",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "723:47:1"
|
||||
},
|
||||
"nodeType": "YulFunctionCall",
|
||||
"src": "723:80:1"
|
||||
},
|
||||
"variableNames":
|
||||
[
|
||||
{
|
||||
"name": "value0",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "705:6:1"
|
||||
},
|
||||
{
|
||||
"name": "value1",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "713:6:1"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "abi_decode_tuple_t_array$_t_uint256_$dyn_calldata_ptr",
|
||||
"nodeType": "YulFunctionDefinition",
|
||||
"parameters":
|
||||
[
|
||||
{
|
||||
"name": "headStart",
|
||||
"nodeType": "YulTypedName",
|
||||
"src": "460:9:1",
|
||||
"type": ""
|
||||
},
|
||||
{
|
||||
"name": "dataEnd",
|
||||
"nodeType": "YulTypedName",
|
||||
"src": "471:7:1",
|
||||
"type": ""
|
||||
}
|
||||
],
|
||||
"returnVariables":
|
||||
[
|
||||
{
|
||||
"name": "value0",
|
||||
"nodeType": "YulTypedName",
|
||||
"src": "483:6:1",
|
||||
"type": ""
|
||||
},
|
||||
{
|
||||
"name": "value1",
|
||||
"nodeType": "YulTypedName",
|
||||
"src": "491:6:1",
|
||||
"type": ""
|
||||
}
|
||||
],
|
||||
"src": "397:423:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"contents": "{\n\n // uint256[]\n function abi_decode_t_array$_t_uint256_$dyn_calldata_ptr(offset, end) -> arrayPos, length {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(arrayPos, mul(length, 0x20)), end) { revert(0, 0) }\n }\n\n function abi_decode_tuple_t_array$_t_uint256_$dyn_calldata_ptr(headStart, dataEnd) -> value0, value1 {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n\n {\n let offset := calldataload(add(headStart, 0))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value0, value1 := abi_decode_t_array$_t_uint256_$dyn_calldata_ptr(add(headStart, offset), dataEnd)\n }\n\n }\n\n}\n",
|
||||
"id": 1,
|
||||
"language": "Yul",
|
||||
"name": "#utility.yul"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"version": "VERSION REMOVED"
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}},"b.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}},"b.sol":{"A1":{"evm":{"bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"},{"component":"general","errorCode":"3420","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","errorCode":"2018","formattedMessage":"b.sol:2:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
|
@ -1,4 +1,4 @@
|
||||
{"contracts":{"a.sol":{"A2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
{"contracts":{"a.sol":{"A2":{"evm":{"bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"},{"component":"general","errorCode":"3420","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","errorCode":"2018","formattedMessage":"b.sol:2:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
|
@ -1,4 +1,4 @@
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"A2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}},"b.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"B2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"A2":{"evm":{"bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}},"b.sol":{"A1":{"evm":{"bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"B2":{"evm":{"bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"},{"component":"general","errorCode":"3420","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","errorCode":"2018","formattedMessage":"b.sol:2:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
|
@ -1,2 +1,2 @@
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{"contracts":{"b.sol":{"B2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
{"contracts":{"b.sol":{"B2":{"evm":{"bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","errorCode":"2018","formattedMessage":"b.sol:2:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^------------------------------------------^
|
||||
|
@ -1,2 +1,2 @@
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"A2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"A2":{"evm":{"bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
20
test/cmdlineTests/standard_generatedSources/input.json
Normal file
20
test/cmdlineTests/standard_generatedSources/input.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"a.sol": {
|
||||
"content": "// SPDX-License-Identifier: GPL-3.0\npragma experimental ABIEncoderV2; contract A { function f(uint[] memory) public view returns (uint256) { } }"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"evmVersion": "petersburg",
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"A": [
|
||||
"evm.bytecode.object",
|
||||
"evm.deployedBytecode.generatedSources",
|
||||
"evm.bytecode.generatedSources"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
77
test/cmdlineTests/standard_generatedSources/output.json
Normal file
77
test/cmdlineTests/standard_generatedSources/output.json
Normal file
File diff suppressed because one or more lines are too long
@ -1,2 +1,2 @@
|
||||
{"contracts":{"a.sol":{"A":{"evm":{"deployedBytecode":{"immutableReferences":{"3":[{"length":32,"start":77}]},"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"36:96:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;108:7;126:1;119:8;;74:56;:::o"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
{"contracts":{"a.sol":{"A":{"evm":{"deployedBytecode":{"generatedSources":[],"immutableReferences":{"3":[{"length":32,"start":77}]},"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"36:96:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;108:7;126:1;119:8;;74:56;:::o"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"}],"sources":{"a.sol":{"id":0}}}
|
||||
|
@ -0,0 +1,21 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"a.sol": {
|
||||
"content": "// SPDX-License-Identifier: GPL-3.0\npragma experimental ABIEncoderV2; contract A { function f(uint[] memory) public view returns (uint256) { } }"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"evmVersion": "petersburg",
|
||||
"optimizer": { "enabled": true },
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"A": [
|
||||
"evm.bytecode.object",
|
||||
"evm.deployedBytecode.generatedSources",
|
||||
"evm.bytecode.generatedSources"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -14,7 +14,7 @@
|
||||
sstore
|
||||
/* \"A\":0:42 */
|
||||
pop
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"object\" {
|
||||
","bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"object\" {
|
||||
code {
|
||||
let x := mload(0)
|
||||
sstore(add(x, 0), 0)
|
||||
|
@ -13,7 +13,7 @@
|
||||
pop
|
||||
stop
|
||||
data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"NamedObject\" {
|
||||
","bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"NamedObject\" {
|
||||
code {
|
||||
let x := dataoffset(\"DataName\")
|
||||
sstore(add(x, 0), 0)
|
||||
|
@ -22,7 +22,7 @@ sub_0: assembly {
|
||||
/* \"A\":137:149 */
|
||||
revert
|
||||
}
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"},"deployedBytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"NamedObject\" {
|
||||
","bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"},"deployedBytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"NamedObject\" {
|
||||
code {
|
||||
let x := dataoffset(\"DataName\")
|
||||
sstore(add(x, 0), 0)
|
||||
|
@ -13,7 +13,7 @@
|
||||
/* \"A\":20:40 */
|
||||
sstore
|
||||
pop
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"object\" {
|
||||
","bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"object\" {
|
||||
code {
|
||||
let x := mload(0)
|
||||
sstore(add(x, 0), 0)
|
||||
|
@ -5,7 +5,7 @@
|
||||
mload
|
||||
/* \"A\":20:40 */
|
||||
sstore
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"object\" {
|
||||
","bytecode":{"generatedSources":[],"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"object\" {
|
||||
code {
|
||||
let x := mload(0)
|
||||
sstore(add(x, 0), 0)
|
||||
|
@ -1,14 +1,14 @@
|
||||
// ---- SOURCE: a
|
||||
==== Source: a ====
|
||||
|
||||
/**This contract is empty*/ contract C {}
|
||||
|
||||
// ---- SOURCE: b
|
||||
==== Source: b ====
|
||||
|
||||
/**This contract is empty
|
||||
and has a line-breaking comment.*/
|
||||
contract C {}
|
||||
|
||||
// ---- SOURCE: c
|
||||
==== Source: c ====
|
||||
|
||||
contract C {
|
||||
/** Some comment on state var.*/ uint public state;
|
||||
|
@ -44,6 +44,8 @@ using namespace boost::unit_test;
|
||||
namespace
|
||||
{
|
||||
|
||||
string const sourceDelimiter("==== Source: ");
|
||||
|
||||
void replaceVersionWithTag(string& _input)
|
||||
{
|
||||
boost::algorithm::replace_all(
|
||||
@ -81,7 +83,6 @@ ASTJSONTest::ASTJSONTest(string const& _filename)
|
||||
string sourceName;
|
||||
string source;
|
||||
string line;
|
||||
string const sourceDelimiter("// ---- SOURCE: ");
|
||||
string const delimiter("// ----");
|
||||
while (getline(file, line))
|
||||
{
|
||||
@ -90,7 +91,10 @@ ASTJSONTest::ASTJSONTest(string const& _filename)
|
||||
if (!sourceName.empty())
|
||||
m_sources.emplace_back(sourceName, source);
|
||||
|
||||
sourceName = line.substr(sourceDelimiter.size(), string::npos);
|
||||
sourceName = line.substr(
|
||||
sourceDelimiter.size(),
|
||||
line.size() - " ===="s.size() - sourceDelimiter.size()
|
||||
);
|
||||
source = string();
|
||||
}
|
||||
else if (!line.empty() && !boost::algorithm::starts_with(line, delimiter))
|
||||
@ -238,7 +242,7 @@ void ASTJSONTest::printSource(ostream& _stream, string const& _linePrefix, bool
|
||||
for (auto const& source: m_sources)
|
||||
{
|
||||
if (m_sources.size() > 1 || source.first != "a")
|
||||
_stream << _linePrefix << "// ---- SOURCE: " << source.first << endl << endl;
|
||||
_stream << _linePrefix << sourceDelimiter << source.first << endl << endl;
|
||||
stringstream stream(source.second);
|
||||
string line;
|
||||
while (getline(stream, line))
|
||||
|
33
test/libsolidity/smtCheckerTests/control_flow/require.sol
Normal file
33
test/libsolidity/smtCheckerTests/control_flow/require.sol
Normal file
@ -0,0 +1,33 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f() pure public {
|
||||
require(false);
|
||||
// This is not reachable.
|
||||
assert(false);
|
||||
}
|
||||
|
||||
function g() pure public {
|
||||
require(false, "require message");
|
||||
// This is not reachable.
|
||||
assert(false);
|
||||
}
|
||||
|
||||
function h(bool b) pure public {
|
||||
if (b)
|
||||
require(false);
|
||||
assert(!b);
|
||||
}
|
||||
|
||||
// Check that arguments are evaluated.
|
||||
bool x = false;
|
||||
function m() view internal returns (string memory) {
|
||||
assert(x != true);
|
||||
}
|
||||
function i() public {
|
||||
x = true;
|
||||
require(false, m());
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (448-465): Assertion violation happens here.
|
35
test/libsolidity/smtCheckerTests/control_flow/revert.sol
Normal file
35
test/libsolidity/smtCheckerTests/control_flow/revert.sol
Normal file
@ -0,0 +1,35 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f() pure public {
|
||||
revert();
|
||||
// This is not reachable.
|
||||
assert(false);
|
||||
}
|
||||
|
||||
function g() pure public {
|
||||
revert("revert message");
|
||||
// This is not reachable.
|
||||
assert(false);
|
||||
}
|
||||
|
||||
function h(bool b) pure public {
|
||||
if (b)
|
||||
revert();
|
||||
assert(!b);
|
||||
}
|
||||
|
||||
// Check that arguments are evaluated.
|
||||
bool x = false;
|
||||
function m() view internal returns (string memory) {
|
||||
assert(x != true);
|
||||
}
|
||||
function i() public {
|
||||
x = true;
|
||||
revert(m());
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 5740: (116-129): Unreachable code.
|
||||
// Warning 5740: (221-234): Unreachable code.
|
||||
// Warning 6328: (427-444): Assertion violation happens here.
|
@ -0,0 +1,18 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f(bool b, uint a) pure public {
|
||||
require(a <= 256);
|
||||
if (b)
|
||||
revert();
|
||||
uint c = a + 1;
|
||||
if (b)
|
||||
c--;
|
||||
else
|
||||
c++;
|
||||
assert(c == a);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (183-197): Assertion violation happens here.
|
||||
// Warning 6838: (155-156): Condition is always false.
|
@ -1,8 +1,5 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
// This test gets different results on Linux and OSX.
|
||||
// Re-enable when fixed (SMTSolvers: z3)
|
||||
|
||||
contract Simple {
|
||||
function f() public pure {
|
||||
uint x = 10;
|
||||
@ -18,8 +15,4 @@ contract Simple {
|
||||
assert(y == x);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// SMTSolvers: none
|
||||
// ----
|
||||
// Warning: (195-209): Error trying to invoke SMT solver.
|
||||
// Warning: (195-209): Assertion violation happens here
|
||||
|
@ -13,8 +13,6 @@ contract C
|
||||
assert(x > 0);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// SMTSolvers: cvc4
|
||||
// ----
|
||||
// Warning 1218: (176-181): Error trying to invoke SMT solver.
|
||||
// Warning 2661: (176-181): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 4661: (296-309): Assertion violation happens here.
|
||||
|
@ -20,9 +20,7 @@ contract LoopFor2 {
|
||||
assert(b[0] == 900);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// SMTSolvers: cvc4
|
||||
// ----
|
||||
// Warning 4661: (296-316): Assertion violation happens here.
|
||||
// Warning 4661: (320-339): Assertion violation happens here.
|
||||
// Warning 4661: (343-362): Assertion violation happens here.
|
||||
// Warning 1218: (229-234): Error trying to invoke SMT solver.
|
||||
// Warning 6328: (320-339): Assertion violation happens here.
|
||||
// Warning 6328: (343-362): Assertion violation happens here.
|
||||
|
@ -37,8 +37,6 @@ contract C {
|
||||
b[x][y] = z;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// SMTSolvers: cvc4
|
||||
// ----
|
||||
// Warning 4661: (372-392): Assertion violation happens here.
|
||||
// Warning 4661: (617-637): Assertion violation happens here.
|
||||
// Warning 6328: (372-392): Assertion violation happens here.
|
||||
// Warning 6328: (617-637): Assertion violation happens here.
|
||||
|
@ -0,0 +1,19 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f(uint8 a, uint8 b) internal pure returns (uint256) {
|
||||
return a >> b;
|
||||
}
|
||||
function t() public pure {
|
||||
assert(f(0x66, 0) == 0x66);
|
||||
// Fails because the above is true.
|
||||
assert(f(0x66, 0) == 0x6);
|
||||
|
||||
assert(f(0x66, 8) == 0);
|
||||
// Fails because the above is true.
|
||||
assert(f(0x66, 8) == 1);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (240-265): Assertion violation happens here.
|
||||
// Warning 6328: (335-358): Assertion violation happens here.
|
@ -0,0 +1,35 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C
|
||||
{
|
||||
mapping (uint => uint) a;
|
||||
mapping (uint => mapping (uint => uint)) maps;
|
||||
mapping (uint => mapping (uint => uint8)) maps8;
|
||||
function f(mapping (uint => uint) storage map1, mapping (uint => uint) storage map2) internal {
|
||||
map1[0] = 2;
|
||||
a[0] = 42;
|
||||
maps[0][0] = 42;
|
||||
maps8[0][0] = 42;
|
||||
map2[0] = 1;
|
||||
// Fails because map2 == map1 is possible.
|
||||
assert(map1[0] == 2);
|
||||
// Fails because map2 == a is possible.
|
||||
assert(a[0] == 42);
|
||||
// Fails because map2 == maps[0] is possible.
|
||||
assert(maps[0][0] == 42);
|
||||
// Should not fail since knowledge is erased only for mapping (uint => uint).
|
||||
assert(maps8[0][0] == 42);
|
||||
assert(map2[0] == 1);
|
||||
}
|
||||
|
||||
function g(bool b, uint x, uint y) public {
|
||||
if (b)
|
||||
f(a, maps[y]);
|
||||
else
|
||||
f(maps[x], maps[y]);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (397-417): Assertion violation happens here.
|
||||
// Warning 6328: (463-481): Assertion violation happens here.
|
||||
// Warning 6328: (533-557): Assertion violation happens here.
|
@ -22,6 +22,8 @@ contract C {
|
||||
assert(s1[2].a[2] == s2.a[2]);
|
||||
s1[0].ts[3].y = 5;
|
||||
assert(s1[0].ts[3].y == s2.ts[3].y);
|
||||
s1[1].ts[4].a[5] = 6;
|
||||
assert(s1[1].ts[4].a[5] == s2.ts[4].a[5]);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
@ -29,4 +31,5 @@ contract C {
|
||||
// Warning 6328: (301-328): Assertion violation happens here.
|
||||
// Warning 6328: (350-379): Assertion violation happens here.
|
||||
// Warning 6328: (404-439): Assertion violation happens here.
|
||||
// Warning 6328: (467-508): Assertion violation happens here.
|
||||
// Warning 4588: (228-238): Assertion checker does not yet implement this type of function call.
|
||||
|
@ -22,6 +22,8 @@ contract C {
|
||||
assert(s1.a[2] != 4);
|
||||
s1.ts[3].y = 5;
|
||||
assert(s1.ts[3].y != 5);
|
||||
s1.ts[4].a[5] = 6;
|
||||
assert(s1.ts[4].a[5] != 6);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
@ -29,3 +31,4 @@ contract C {
|
||||
// Warning 6328: (263-282): Assertion violation happens here.
|
||||
// Warning 6328: (301-321): Assertion violation happens here.
|
||||
// Warning 6328: (343-366): Assertion violation happens here.
|
||||
// Warning 6328: (391-417): Assertion violation happens here.
|
||||
|
@ -0,0 +1,34 @@
|
||||
pragma experimental SMTChecker;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct T {
|
||||
uint y;
|
||||
uint[] a;
|
||||
}
|
||||
struct S {
|
||||
uint x;
|
||||
T t;
|
||||
uint[] a;
|
||||
T[] ts;
|
||||
}
|
||||
function f(S memory s2) public pure {
|
||||
S memory s1;
|
||||
s1.x = 2;
|
||||
assert(s1.x == s2.x);
|
||||
s1.t.y = 3;
|
||||
assert(s1.t.y == s2.t.y);
|
||||
s1.a[2] = 4;
|
||||
assert(s1.a[2] == s2.a[2]);
|
||||
s1.ts[3].y = 5;
|
||||
assert(s1.ts[3].y == s2.ts[3].y);
|
||||
s1.ts[4].a[5] = 6;
|
||||
assert(s1.ts[4].a[5] == s2.ts[4].a[5]);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (239-259): Assertion violation happens here.
|
||||
// Warning 6328: (277-301): Assertion violation happens here.
|
||||
// Warning 6328: (320-346): Assertion violation happens here.
|
||||
// Warning 6328: (368-400): Assertion violation happens here.
|
||||
// Warning 6328: (425-463): Assertion violation happens here.
|
@ -21,6 +21,8 @@ contract C {
|
||||
assert(s1.a[2] != 4);
|
||||
s1.ts[3].y = 5;
|
||||
assert(s1.ts[3].y != 5);
|
||||
s1.ts[4].a[5] = 6;
|
||||
assert(s1.ts[4].a[5] != 6);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
@ -28,3 +30,4 @@ contract C {
|
||||
// Warning 6328: (216-235): Assertion violation happens here.
|
||||
// Warning 6328: (254-274): Assertion violation happens here.
|
||||
// Warning 6328: (296-319): Assertion violation happens here.
|
||||
// Warning 6328: (344-370): Assertion violation happens here.
|
||||
|
32
test/libsolidity/smtCheckerTests/types/type_interfaceid.sol
Normal file
32
test/libsolidity/smtCheckerTests/types/type_interfaceid.sol
Normal file
@ -0,0 +1,32 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
interface I1 {
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
function f() external;
|
||||
}
|
||||
|
||||
interface I3 {
|
||||
function f() external;
|
||||
function g(uint, address) external;
|
||||
}
|
||||
|
||||
contract C {
|
||||
function f() public pure {
|
||||
assert(type(I1).interfaceId == 0);
|
||||
assert(type(I2).interfaceId != 0);
|
||||
assert(type(I2).interfaceId == 0x26121ff0);
|
||||
assert(type(I2).interfaceId != 0);
|
||||
assert(type(I3).interfaceId == 0x822b51c6);
|
||||
}
|
||||
function g() public pure {
|
||||
assert(type(I1).interfaceId == type(I2).interfaceId);
|
||||
}
|
||||
function h() public pure {
|
||||
assert(type(I2).interfaceId == type(I3).interfaceId);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (449-501): Assertion violation happens here.
|
||||
// Warning 6328: (536-588): Assertion violation happens here.
|
@ -6,4 +6,3 @@ contract C {
|
||||
}
|
||||
// ----
|
||||
// Warning 6838: (94-100): Condition is always true.
|
||||
// Warning 4588: (104-112): Assertion checker does not yet implement this type of function call.
|
||||
|
@ -6,4 +6,3 @@ contract C {
|
||||
}
|
||||
// ----
|
||||
// Warning 6838: (109-115): Condition is always false.
|
||||
// Warning 4588: (119-127): Assertion checker does not yet implement this type of function call.
|
||||
|
@ -6,4 +6,3 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 4588: (136-144): Assertion checker does not yet implement this type of function call.
|
||||
|
@ -0,0 +1,6 @@
|
||||
contract test {
|
||||
function e() external { }
|
||||
function f() public pure { uint e; e = 0; }
|
||||
}
|
||||
// ----
|
||||
// Warning 8760: (77-83): This declaration has the same name as another declaration.
|
6
test/libsolidity/syntaxTests/scoping/name_shadowing2.sol
Normal file
6
test/libsolidity/syntaxTests/scoping/name_shadowing2.sol
Normal file
@ -0,0 +1,6 @@
|
||||
function e() {}
|
||||
contract test {
|
||||
function f() pure public { uint e; e = 0; }
|
||||
}
|
||||
// ----
|
||||
// Warning 2519: (63-69): This declaration shadows an existing declaration.
|
@ -126,149 +126,6 @@ do \
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(YulParser)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(smoke_test)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(vardecl)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ let x:u256 := 7:u256 }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(vardecl_bool)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ let x:bool := true:bool }"));
|
||||
BOOST_CHECK(successParse("{ let x:bool := false:bool }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(vardecl_empty)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ let x:u256 }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(assignment)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ let x:u256 := 2:u256 let y:u256 := x }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(period_in_identifier)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ let x.y:u256 := 2:u256 }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(period_not_as_identifier_start)
|
||||
{
|
||||
CHECK_ERROR("{ let .y:u256 }", ParserError, "Expected identifier but got '.'");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(period_in_identifier_spaced)
|
||||
{
|
||||
CHECK_ERROR("{ let x. y:u256 }", ParserError, "Call or assignment expected");
|
||||
CHECK_ERROR("{ let x .y:u256 }", ParserError, "Literal or identifier expected");
|
||||
CHECK_ERROR("{ let x . y:u256 }", ParserError, "Literal or identifier expected");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(period_in_identifier_start)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ x.y(2:u256) function x.y(a:u256) {} }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(period_in_identifier_start_with_comment)
|
||||
{
|
||||
BOOST_CHECK(successParse("/// comment\n{ x.y(2:u256) function x.y(a:u256) {} }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(vardecl_complex)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ function add(a:u256, b:u256) -> c:u256 {} let y:u256 := 2:u256 let x:u256 := add(7:u256, add(6:u256, y)) }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(blocks)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ let x:u256 := 7:u256 { let y:u256 := 3:u256 } { let z:u256 := 2:u256 } }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(function_definitions)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ function f() { } function g(a:u256) -> x:u256 { } }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(function_definitions_multiple_args)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ function f(a:u256, d:u256) { } function g(a:u256, d:u256) -> x:u256, y:u256 { } }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(function_calls)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ function f(a:u256) -> b:u256 {} function g(a:u256, b:u256, c:u256) {} function x() { g(1:u256, 2:u256, f(3:u256)) x() } }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(tuple_assignment)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ function f() -> a:u256, b:u256, c:u256 {} let x:u256, y:u256, z:u256 := f() }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(instructions)
|
||||
{
|
||||
CHECK_ERROR("{ pop }", ParserError, "Call or assignment expected.");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(push)
|
||||
{
|
||||
CHECK_ERROR("{ 0x42:u256 }", ParserError, "Call or assignment expected.");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(assign_from_stack)
|
||||
{
|
||||
CHECK_ERROR("{ =: x:u256 }", ParserError, "Literal or identifier expected.");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty_call)
|
||||
{
|
||||
CHECK_ERROR("{ () }", ParserError, "Literal or identifier expected.");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(tokens_as_identifers)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ let return:u256 := 1:u256 }"));
|
||||
BOOST_CHECK(successParse("{ let byte:u256 := 1:u256 }"));
|
||||
BOOST_CHECK(successParse("{ let address:u256 := 1:u256 }"));
|
||||
BOOST_CHECK(successParse("{ let bool:u256 := 1:u256 }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(optional_types)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ let x := 1:u256 }"));
|
||||
BOOST_CHECK(successParse("{ let x:u256 := 1 }"));
|
||||
BOOST_CHECK(successParse("{ function f(a) {} }"));
|
||||
BOOST_CHECK(successParse("{ function f(a:u256) -> b {} }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(number_literals)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ let x:u256 := 1:u256 }"));
|
||||
CHECK_ERROR("{ let x:u256 := .1:u256 }", ParserError, "Invalid number literal.");
|
||||
CHECK_ERROR("{ let x:u256 := 1e5:u256 }", ParserError, "Invalid number literal.");
|
||||
CHECK_ERROR("{ let x:u256 := 67.235:u256 }", ParserError, "Invalid number literal.");
|
||||
CHECK_ERROR("{ let x:u256 := 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:u256 }", TypeError, "Number literal too large (> 256 bits)");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(builtin_types)
|
||||
{
|
||||
BOOST_CHECK(successParse("{ let x:bool := true:bool }"));
|
||||
BOOST_CHECK(successParse("{ let x:u8 := 1:u8 }"));
|
||||
BOOST_CHECK(successParse("{ let x:s8 := 1:s8 }"));
|
||||
BOOST_CHECK(successParse("{ let x:u32 := 1:u32 }"));
|
||||
BOOST_CHECK(successParse("{ let x:s32 := 1:s32 }"));
|
||||
BOOST_CHECK(successParse("{ let x:u64 := 1:u64 }"));
|
||||
BOOST_CHECK(successParse("{ let x:s64 := 1:s64 }"));
|
||||
BOOST_CHECK(successParse("{ let x:u128 := 1:u128 }"));
|
||||
BOOST_CHECK(successParse("{ let x:s128 := 1:s128 }"));
|
||||
BOOST_CHECK(successParse("{ let x:u256 := 1:u256 }"));
|
||||
BOOST_CHECK(successParse("{ let x:s256 := 1:s256 }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(recursion_depth)
|
||||
{
|
||||
string input;
|
||||
|
3
test/libyul/yulSyntaxTests/assign_from_stack.yul
Normal file
3
test/libyul/yulSyntaxTests/assign_from_stack.yul
Normal file
@ -0,0 +1,3 @@
|
||||
{ =: x:u256 }
|
||||
// ----
|
||||
// ParserError 1856: (2-3): Literal or identifier expected.
|
4
test/libyul/yulSyntaxTests/assignment.yul
Normal file
4
test/libyul/yulSyntaxTests/assignment.yul
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
let x:u256 := 2:u256
|
||||
let y:u256 := x
|
||||
}
|
9
test/libyul/yulSyntaxTests/blocks.yul
Normal file
9
test/libyul/yulSyntaxTests/blocks.yul
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
let x:u256 := 7:u256
|
||||
{
|
||||
let y:u256 := 3:u256
|
||||
}
|
||||
{
|
||||
let z:u256 := 2:u256
|
||||
}
|
||||
}
|
15
test/libyul/yulSyntaxTests/builtin_types.yul
Normal file
15
test/libyul/yulSyntaxTests/builtin_types.yul
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
let x1:bool := true:bool
|
||||
let x2:u8 := 1:u8
|
||||
let x3:s8 := 1:s8
|
||||
let x4:u32 := 1:u32
|
||||
let x5:s32 := 1:s32
|
||||
let x6:u64 := 1:u64
|
||||
let x7:s64 := 1:s64
|
||||
let x8:u128 := 1:u128
|
||||
let x9:s128 := 1:s128
|
||||
let x10:u256 := 1:u256
|
||||
let x11:s256 := 1:s256
|
||||
}
|
||||
// ====
|
||||
// dialect: yul
|
3
test/libyul/yulSyntaxTests/empty_call.yul
Normal file
3
test/libyul/yulSyntaxTests/empty_call.yul
Normal file
@ -0,0 +1,3 @@
|
||||
{ () }
|
||||
// ----
|
||||
// ParserError 1856: (2-3): Literal or identifier expected.
|
8
test/libyul/yulSyntaxTests/function_calls.yul
Normal file
8
test/libyul/yulSyntaxTests/function_calls.yul
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
function f(a:u256) -> b:u256 {}
|
||||
function g(a:u256, b:u256, c:u256) {}
|
||||
function x() {
|
||||
g(1:u256, 2:u256, f(3:u256))
|
||||
x()
|
||||
}
|
||||
}
|
4
test/libyul/yulSyntaxTests/function_definitions.yul
Normal file
4
test/libyul/yulSyntaxTests/function_definitions.yul
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
function f() { }
|
||||
function g(a:u256) -> x:u256 { }
|
||||
}
|
4
test/libyul/yulSyntaxTests/functions_multiple_args.yul
Normal file
4
test/libyul/yulSyntaxTests/functions_multiple_args.yul
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
function f(a:u256, d:u256) { }
|
||||
function g(a:u256, d:u256) -> x:u256, y:u256 { }
|
||||
}
|
5
test/libyul/yulSyntaxTests/instructions.yul
Normal file
5
test/libyul/yulSyntaxTests/instructions.yul
Normal file
@ -0,0 +1,5 @@
|
||||
{ pop }
|
||||
// ====
|
||||
// dialect: yul
|
||||
// ----
|
||||
// ParserError 6913: (6-7): Call or assignment expected.
|
1
test/libyul/yulSyntaxTests/number_literal_1.yul
Normal file
1
test/libyul/yulSyntaxTests/number_literal_1.yul
Normal file
@ -0,0 +1 @@
|
||||
{ let x:u256 := 1:u256 }
|
3
test/libyul/yulSyntaxTests/number_literal_2.yul
Normal file
3
test/libyul/yulSyntaxTests/number_literal_2.yul
Normal file
@ -0,0 +1,3 @@
|
||||
{ let x:u256 := .1:u256 }
|
||||
// ----
|
||||
// ParserError 4828: (16-18): Invalid number literal.
|
3
test/libyul/yulSyntaxTests/number_literal_3.yul
Normal file
3
test/libyul/yulSyntaxTests/number_literal_3.yul
Normal file
@ -0,0 +1,3 @@
|
||||
{ let x:u256 := 1e5:u256 }
|
||||
// ----
|
||||
// ParserError 4828: (16-19): Invalid number literal.
|
3
test/libyul/yulSyntaxTests/number_literal_4.yul
Normal file
3
test/libyul/yulSyntaxTests/number_literal_4.yul
Normal file
@ -0,0 +1,3 @@
|
||||
{ let x:u256 := 67.235:u256 }
|
||||
// ----
|
||||
// ParserError 4828: (16-22): Invalid number literal.
|
3
test/libyul/yulSyntaxTests/number_literal_5.yul
Normal file
3
test/libyul/yulSyntaxTests/number_literal_5.yul
Normal file
@ -0,0 +1,3 @@
|
||||
{ let x:u256 := 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:u256 }
|
||||
// ----
|
||||
// TypeError 6708: (16-88): Number literal too large (> 256 bits)
|
8
test/libyul/yulSyntaxTests/optional_types.yul
Normal file
8
test/libyul/yulSyntaxTests/optional_types.yul
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
let x := 1:u256
|
||||
let y:u256 := 1
|
||||
function f(a) {}
|
||||
function g(a:u256) -> b {}
|
||||
}
|
||||
// ====
|
||||
// dialect: yul
|
1
test/libyul/yulSyntaxTests/period_in_identifier.yul
Normal file
1
test/libyul/yulSyntaxTests/period_in_identifier.yul
Normal file
@ -0,0 +1 @@
|
||||
{ let x.y:u256 := 2:u256 }
|
@ -0,0 +1,3 @@
|
||||
{ let x. y:u256 }
|
||||
// ----
|
||||
// ParserError 6913: (10-11): Call or assignment expected.
|
@ -0,0 +1,3 @@
|
||||
{ let x .y:u256 }
|
||||
// ----
|
||||
// ParserError 1856: (8-9): Literal or identifier expected.
|
@ -0,0 +1,3 @@
|
||||
{ let x . y:u256 }
|
||||
// ----
|
||||
// ParserError 1856: (8-9): Literal or identifier expected.
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
x.y(2:u256)
|
||||
function x.y(a:u256) {}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
/// comment
|
||||
{ x.y(2:u256) function x.y(a:u256) {} }
|
@ -0,0 +1,3 @@
|
||||
{ let .y:u256 }
|
||||
// ----
|
||||
// ParserError 2314: (6-7): Expected identifier but got '.'
|
3
test/libyul/yulSyntaxTests/push.yul
Normal file
3
test/libyul/yulSyntaxTests/push.yul
Normal file
@ -0,0 +1,3 @@
|
||||
{ 0x42:u256 }
|
||||
// ----
|
||||
// ParserError 6913: (12-13): Call or assignment expected.
|
1
test/libyul/yulSyntaxTests/smoke.yul
Normal file
1
test/libyul/yulSyntaxTests/smoke.yul
Normal file
@ -0,0 +1 @@
|
||||
{}
|
8
test/libyul/yulSyntaxTests/token_as_identifier.yul
Normal file
8
test/libyul/yulSyntaxTests/token_as_identifier.yul
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
let return:u256 := 1:u256
|
||||
let byte:u256 := 1:u256
|
||||
let address:u256 := 1:u256
|
||||
let bool:u256 := 1:u256
|
||||
}
|
||||
// ====
|
||||
// dialect: yul
|
4
test/libyul/yulSyntaxTests/tuple_assignment.yul
Normal file
4
test/libyul/yulSyntaxTests/tuple_assignment.yul
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
function f() -> a:u256, b:u256, c:u256 {}
|
||||
let x:u256, y:u256, z:u256 := f()
|
||||
}
|
3
test/libyul/yulSyntaxTests/variable_declaration.yul
Normal file
3
test/libyul/yulSyntaxTests/variable_declaration.yul
Normal file
@ -0,0 +1,3 @@
|
||||
{ let x:u256 := 7:u256 }
|
||||
// ====
|
||||
// dialect: evmTyped
|
6
test/libyul/yulSyntaxTests/variable_declaration_bool.yul
Normal file
6
test/libyul/yulSyntaxTests/variable_declaration_bool.yul
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
let x:bool := true:bool
|
||||
let y:bool := false:bool
|
||||
}
|
||||
// ====
|
||||
// dialect: evmTyped
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
function add(a:u256, b:u256) -> c:u256 {}
|
||||
let y:u256 := 2:u256
|
||||
let x:u256 := add(7:u256, add(6:u256, y))
|
||||
}
|
||||
// ====
|
||||
// dialect: yul
|
@ -0,0 +1 @@
|
||||
{ let x:u256 }
|
Loading…
Reference in New Issue
Block a user