Merge remote-tracking branch 'origin/develop' into breaking

This commit is contained in:
chriseth 2020-11-24 16:22:03 +01:00
commit 253889cbf1
322 changed files with 1066 additions and 403 deletions

View File

@ -27,10 +27,15 @@ AST Changes:
### 0.7.6 (unreleased)
Language Features:
* The fallback function can now also have a single ``calldata`` argument (equaling ``msg.data``) and return ``bytes memory`` (which will not be ABI-encoded but returned as-is).
Compiler Features:
* Code Generator: Avoid memory allocation for default value if it is not used.
* SMTChecker: Support named arguments in function calls.
* SMTChecker: Support struct constructor.
### 0.7.5 (2020-11-18)
Language Features:

View File

@ -275,7 +275,10 @@ A contract can have at most one ``receive`` function, declared using
``receive() external payable { ... }``
(without the ``function`` keyword).
This function cannot have arguments, cannot return anything and must have
``external`` visibility and ``payable`` state mutability. It is executed on a
``external`` visibility and ``payable`` state mutability.
It can be virtual, can override and can have modifiers.
The receive function is executed on a
call to the contract with empty calldata. This is the function that is executed
on plain Ether transfers (e.g. via ``.send()`` or ``.transfer()``). If no such
function exists, but a payable :ref:`fallback function <fallback-function>`
@ -339,15 +342,22 @@ Below you can see an example of a Sink contract that uses function ``receive``.
Fallback Function
=================
A contract can have at most one ``fallback`` function, declared using ``fallback () external [payable]``
(without the ``function`` keyword).
This function cannot have arguments, cannot return anything and must have ``external`` visibility.
It is executed on a call to the contract if none of the other
A contract can have at most one ``fallback`` function, declared using either ``fallback () external [payable]``
or ``fallback (bytes calldata _input) external [payable] returns (bytes memory _output)``
(both without the ``function`` keyword).
This function must have ``external`` visibility. A fallback function can be virtual, can override
and can have modifiers.
The fallback function is executed on a call to the contract if none of the other
functions match the given function signature, or if no data was supplied at
all and there is no :ref:`receive Ether function <receive-ether-function>`.
The fallback function always receives data, but in order to also receive Ether
it must be marked ``payable``.
If the version with parameters is used, ``_input`` will contain the full data sent to the contract
(equal to ``msg.data``) and can return data in ``_output``. The returned data will not be
ABI-encoded. Instead it will be returned without modifications (not even padding).
In the worst case, if a payable fallback function is also used in
place of a receive function, it can only rely on 2300 gas being
available (see :ref:`receive Ether function <receive-ether-function>`
@ -364,12 +374,11 @@ operations as long as there is enough gas passed on to it.
to distinguish Ether transfers from interface confusions.
.. note::
Even though the fallback function cannot have arguments, one can still use ``msg.data`` to retrieve
any payload supplied with the call.
After having checked the first four bytes of ``msg.data``,
If you want to decode the input data, you can check the first four bytes
for the function selector and then
you can use ``abi.decode`` together with the array slice syntax to
decode ABI-encoded data:
``(c, d) = abi.decode(msg.data[4:], (uint256, uint256));``
``(c, d) = abi.decode(_input[4:], (uint256, uint256));``
Note that this should only be used as a last resort and
proper functions should be used instead.

View File

@ -84,7 +84,8 @@ contractBodyElement:
constructorDefinition
| functionDefinition
| modifierDefinition
| fallbackReceiveFunctionDefinition
| fallbackFunctionDefinition
| receiveFunctionDefinition
| structDefinition
| enumDefinition
| stateVariableDeclaration
@ -189,9 +190,32 @@ locals[
(Semicolon | body=block);
/**
* Definitions of the special fallback and receive functions.
* Definition of the special fallback function.
*/
fallbackReceiveFunctionDefinition
fallbackFunctionDefinition
locals[
boolean visibilitySet = false,
boolean mutabilitySet = false,
boolean virtualSet = false,
boolean overrideSpecifierSet = false,
boolean hasParameters = false
]
:
kind=Fallback LParen (parameterList { $hasParameters = true; } )? RParen
(
{!$visibilitySet}? External {$visibilitySet = true;}
| {!$mutabilitySet}? stateMutability {$mutabilitySet = true;}
| modifierInvocation
| {!$virtualSet}? Virtual {$virtualSet = true;}
| {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;}
)*
( {$hasParameters}? Returns LParen returnParameters=parameterList RParen | {!$hasParameters}? )
(Semicolon | body=block);
/**
* Definition of the special receive function.
*/
receiveFunctionDefinition
locals[
boolean visibilitySet = false,
boolean mutabilitySet = false,
@ -199,10 +223,10 @@ locals[
boolean overrideSpecifierSet = false
]
:
kind=(Fallback | Receive) LParen RParen
kind=Receive LParen RParen
(
{!$visibilitySet}? visibility {$visibilitySet = true;}
| {!$mutabilitySet}? stateMutability {$mutabilitySet = true;}
{!$visibilitySet}? External {$visibilitySet = true;}
| {!$mutabilitySet}? Payable {$mutabilitySet = true;}
| modifierInvocation
| {!$virtualSet}? Virtual {$virtualSet = true;}
| {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;}

View File

@ -92,8 +92,8 @@ When using this interface it is not necessary to mount any directories.
docker run ethereum/solc:stable --standard-json < input.json > output.json
Binary Packages
===============
Linux Packages
==============
Binary packages of Solidity are available at
`solidity/releases <https://github.com/ethereum/solidity/releases>`_.
@ -143,6 +143,16 @@ Arch Linux also has packages, albeit limited to the latest development version:
pacman -S solidity
Gentoo Linux has an `Ethereum overlay <https://overlays.gentoo.org/#ethereum>`_ that contains a Solidity package.
After the overlay is setup, ``solc`` can be installed in x86_64 architectures by:
.. code-block:: bash
emerge dev-lang/solidity
macOS Packages
==============
We distribute the Solidity compiler through Homebrew
as a build-from-source version. Pre-built bottles are
currently not supported.
@ -179,12 +189,109 @@ Install it using ``brew``:
# eg. Install 0.4.8
brew install solidity.rb
Gentoo Linux has an `Ethereum overlay <https://overlays.gentoo.org/#ethereum>`_ that contains a solidity package.
After the overlay is setup, ``solc`` can be installed in x86_64 architectures by:
Static Binaries
===============
.. code-block:: bash
We maintain a repository containing static builds of past and current compiler versions for all
supported platforms at `solc-bin`_. This is also the location where you can find the nightly builds.
emerge dev-lang/solidity
The repository is not only a quick and easy way for end users to get binaries ready to be used
out-of-the-box but it is also meant to be friendly to third-party tools:
- The content is mirrored to https://binaries.soliditylang.org where it can be easily downloaded over
HTTPS without any authentication, rate limiting or the need to use git.
- Content is served with correct `Content-Type` headers and lenient CORS configuration so that it
can be directly loaded by tools running in the browser.
- Binaries do not require installation or unpacking (with the exception of older Windows builds
bundled with necessary DLLs).
- We strive for a high level of backwards-compatibility. Files, once added, are not removed or moved
without providing a symlink/redirect at the old location. They are also never modified
in place and should always match the original checksum. The only exception would be broken or
unusable files with a potential to cause more harm than good if left as is.
- Files are served over both HTTP and HTTPS. As long as you obtain the file list in a secure way
(via git, HTTPS, IPFS or just have it cached locally) and verify hashes of the binaries
after downloading them, you do not have to use HTTPS for the binaries themselves.
The same binaries are in most cases available on the `Solidity release page on Github`_. The
difference is that we do not generally update old releases on the Github release page. This means
that we do not rename them if the naming convention changes and we do not add builds for platforms
that were not supported at the time of release. This only happens in ``solc-bin``.
The ``solc-bin`` repository contains several top-level directories, each representing a single platform.
Each one contains a ``list.json`` file listing the available binaries. For example in
``emscripten-wasm32/list.json`` you will find the following information about version 0.7.4:
.. code-block:: json
{
"path": "solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js",
"version": "0.7.4",
"build": "commit.3f05b770",
"longVersion": "0.7.4+commit.3f05b770",
"keccak256": "0x300330ecd127756b824aa13e843cb1f43c473cb22eaf3750d5fb9c99279af8c3",
"urls": [
"bzzr://16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1",
"dweb:/ipfs/QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS"
]
}
This means that:
- You can find the binary in the same directory under the name
`solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js <https://github.com/ethereum/solc-bin/blob/gh-pages/emscripten-wasm32/solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js>`_.
Note that the file might be a symlink, and you will need to resolve it yourself if you are not using
git to download it or your file system does not support symlinks.
- The binary is also mirrored at https://binaries.soliditylang.org/emscripten-wasm32/solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js.
In this case git is not necessary and symlinks are resolved transparently, either by serving a copy
of the file or returning a HTTP redirect.
- The file is also available on IPFS at `QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS`_.
- The file might in future be available on Swarm at `16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1`_.
- You can verify the integrity of the binary by comparing its keccak256 hash to
``0x300330ecd127756b824aa13e843cb1f43c473cb22eaf3750d5fb9c99279af8c3``. The hash can be computed
on the command line using ``keccak256sum`` utility provided by `sha3sum`_ or `keccak256() function
from ethereumjs-util`_ in JavaScript.
.. warning::
Due to the strong backwards compatibility requirement the repository contains some legacy elements
but you should avoid using them when writing new tools:
- Use ``emscripten-wasm32/`` (with a fallback to ``emscripten-asmjs/``) instead of ``bin/`` if
you want the best performance. Until version 0.6.1 we only provided asm.js binaries.
Starting with 0.6.2 we switched to `WebAssembly builds`_ with much better performance. We have
rebuilt the older versions for wasm but the original asm.js files remain in ``bin/``.
The new ones had to be placed in a separate directory to avoid name clashes.
- Use ``emscripten-asmjs/`` and ``emscripten-wasm32/`` instead of ``bin/`` and ``wasm/`` directories
if you want to be sure whether you are downloading a wasm or an asm.js binary.
- Use ``list.json`` instead of ``list.js`` and ``list.txt``. The JSON list format contains all
the information from the old ones and more.
- Use https://binaries.soliditylang.org instead of https://solc-bin.ethereum.org. To keep things
simple we moved almost everything related to the compiler under the new ``soliditylang.org``
domain and this applies to ``solc-bin`` too. While the new domain is recommended, the old one
is still fully supported and guaranteed to point at the same location.
.. warning::
The binaries are also available at https://ethereum.github.io/solc-bin/ but this page
stopped being updated just after the release of version 0.7.2, will not receive any new releases
or nightly builds for any platform and does not serve the new directory structure, including
non-emscripten builds.
If you are using it, please switch to https://binaries.soliditylang.org, which is a drop-in
replacement. This allows us to make changes to the underlying hosting in a transparent way and
minimize disruption. Unlike the ``ethereum.github.io`` domain, which we do not have any control
over, ``binaries.soliditylang.org`` is guaranteed to work and maintain the same URL structure
in the long-term.
.. _IPFS: https://ipfs.io
.. _Swarm: https://swarm-gateways.net/bzz:/swarm.eth
.. _solc-bin: https://github.com/ethereum/solc-bin/
.. _Solidity release page on github: https://github.com/ethereum/solidity/releases
.. _sha3sum: https://github.com/maandree/sha3sum
.. _keccak256() function from ethereumjs-util: https://github.com/ethereumjs/ethereumjs-util/blob/master/docs/modules/_hash_.md#const-keccak256
.. _WebAssembly builds: https://emscripten.org/docs/compiling/WebAssembly.html
.. _QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS: https://gateway.ipfs.io/ipfs/QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS
.. _16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1: https://swarm-gateways.net/bzz:/16c5f09109c793db99fe35f037c6092b061bd39260ee7a677c8a97f18c955ab1/
.. _building-from-source:
@ -271,7 +378,7 @@ If you already have one IDE and only need the compiler and libraries,
you could install Visual Studio 2019 Build Tools.
Visual Studio 2019 provides both IDE and necessary compiler and libraries.
So if you have not got an IDE and prefer to develop solidity, Visual Studio 2019
So if you have not got an IDE and prefer to develop Solidity, Visual Studio 2019
may be a choice for you to get everything setup easily.
Here is the list of components that should be installed
@ -338,10 +445,12 @@ Command-Line Build
**Be sure to install External Dependencies (see above) before build.**
Solidity project uses CMake to configure the build.
You might want to install ccache to speed up repeated builds.
You might want to install `ccache`_ to speed up repeated builds.
CMake will pick it up automatically.
Building Solidity is quite similar on Linux, macOS and other Unices:
.. _ccache: https://ccache.dev/
.. code-block:: bash
mkdir build
@ -381,7 +490,7 @@ Alternatively, you can build for Windows on the command-line, like so:
cmake --build . --config Release
CMake options
CMake Options
=============
If you are interested what CMake options are available run ``cmake .. -LH``.
@ -409,7 +518,7 @@ Inside the build folder you can disable them, since they are enabled by default:
# disables both Z3 and CVC4
cmake .. -DUSE_CVC4=OFF -DUSE_Z3=OFF
The version string in detail
The Version String in Detail
============================
The Solidity version string contains four parts:
@ -428,7 +537,7 @@ A release example: ``0.4.8+commit.60cc1668.Emscripten.clang``.
A pre-release example: ``0.4.9-nightly.2017.1.17+commit.6ecb4aa3.Emscripten.clang``
Important information about versioning
Important Information About Versioning
======================================
After a release is made, the patch version level is bumped, because we assume that only

View File

@ -394,6 +394,10 @@ bool OverrideProxy::OverrideComparator::operator<(OverrideComparator const& _oth
if (functionKind != _other.functionKind)
return *functionKind < *_other.functionKind;
// Parameters do not matter for non-regular functions.
if (functionKind != Token::Function)
return false;
if (!parameterTypes || !_other.parameterTypes)
return false;
@ -574,16 +578,19 @@ void OverrideChecker::checkOverride(OverrideProxy const& _overriding, OverridePr
FunctionType const* functionType = _overriding.functionType();
FunctionType const* superType = _super.functionType();
solAssert(functionType->hasEqualParameterTypes(*superType), "Override doesn't have equal parameters!");
if (_overriding.functionKind() != Token::Fallback)
{
solAssert(functionType->hasEqualParameterTypes(*superType), "Override doesn't have equal parameters!");
if (!functionType->hasEqualReturnTypes(*superType))
overrideError(
_overriding,
_super,
4822_error,
"Overriding " + _overriding.astNodeName() + " return types differ.",
"Overridden " + _overriding.astNodeName() + " is here:"
);
if (!functionType->hasEqualReturnTypes(*superType))
overrideError(
_overriding,
_super,
4822_error,
"Overriding " + _overriding.astNodeName() + " return types differ.",
"Overridden " + _overriding.astNodeName() + " is here:"
);
}
// Stricter mutability is always okay except when super is Payable
if (

View File

@ -1846,15 +1846,21 @@ void TypeChecker::typeCheckFallbackFunction(FunctionDefinition const& _function)
);
if (_function.visibility() != Visibility::External)
m_errorReporter.typeError(1159_error, _function.location(), "Fallback function must be defined as \"external\".");
if (!_function.returnParameters().empty())
if (!_function.returnParameters().empty() || !_function.parameters().empty())
{
if (_function.returnParameters().size() > 1 || *type(*_function.returnParameters().front()) != *TypeProvider::bytesMemory())
m_errorReporter.typeError(5570_error, _function.returnParameterList()->location(), "Fallback function can only have a single \"bytes memory\" return value.");
else
m_errorReporter.typeError(6151_error, _function.returnParameterList()->location(), "Return values for fallback functions are not yet implemented.");
if (
_function.returnParameters().size() != 1 ||
*type(*_function.returnParameters().front()) != *TypeProvider::bytesMemory() ||
_function.parameters().size() != 1 ||
*type(*_function.parameters().front()) != *TypeProvider::bytesCalldata()
)
m_errorReporter.typeError(
5570_error,
_function.returnParameterList()->location(),
"Fallback function either has to have the signature \"fallback()\" or \"fallback(bytes calldata) returns (bytes memory)\"."
);
}
if (!_function.parameters().empty())
m_errorReporter.typeError(3978_error, _function.parameterList().location(), "Fallback function cannot take parameters.");
}
void TypeChecker::typeCheckReceiveFunction(FunctionDefinition const& _function)

View File

@ -170,6 +170,11 @@ public:
/// signature: (dataOffset, length, dataEnd) -> decodedArray
std::string abiDecodingFunctionArrayAvailableLength(ArrayType const& _type, bool _fromMemory);
/// Internal decoding function that is also used by some copying routines.
/// @returns the name of a function that decodes structs.
/// signature: (dataStart, dataEnd) -> decodedStruct
std::string abiDecodingFunctionStruct(StructType const& _type, bool _fromMemory);
private:
/// Part of @a abiEncodingFunction for array target type and given calldata array.
/// Uses calldatacopy and does not perform cleanup or validation and can therefore only
@ -245,8 +250,6 @@ private:
std::string abiDecodingFunctionCalldataStruct(StructType const& _type);
/// Part of @a abiDecodingFunction for array types.
std::string abiDecodingFunctionFunctionType(FunctionType const& _type, bool _fromMemory, bool _forUseOnStack);
/// Part of @a abiDecodingFunction for struct types.
std::string abiDecodingFunctionStruct(StructType const& _type, bool _fromMemory);
/// @returns the name of a function that retrieves an element from calldata.
std::string calldataAccessFunction(Type const& _type);

View File

@ -478,10 +478,21 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac
appendCallValueCheck();
solAssert(fallback->isFallback(), "");
solAssert(FunctionType(*fallback).parameterTypes().empty(), "");
solAssert(FunctionType(*fallback).returnParameterTypes().empty(), "");
m_context.setStackOffset(0);
if (!FunctionType(*fallback).parameterTypes().empty())
m_context << u256(0) << Instruction::CALLDATASIZE;
fallback->accept(*this);
m_context << Instruction::STOP;
if (FunctionType(*fallback).returnParameterTypes().empty())
m_context << Instruction::STOP;
else
{
m_context << Instruction::DUP1 << Instruction::MLOAD << Instruction::SWAP1;
m_context << u256(0x20) << Instruction::ADD;
m_context << Instruction::RETURN;
}
}
else
m_context.appendRevert("Unknown signature and no fallback defined");
@ -490,6 +501,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac
for (auto const& it: interfaceFunctions)
{
m_context.setStackOffset(1);
FunctionTypePointer const& functionType = it.second;
solAssert(functionType->hasDeclaration(), "");
CompilerContext::LocationSetter locationSetter(m_context, functionType->declaration());
@ -599,7 +611,9 @@ bool ContractCompiler::visit(FunctionDefinition const& _function)
// reserve additional slots: [retarg0] ... [retargm]
unsigned parametersSize = CompilerUtils::sizeOnStack(_function.parameters());
if (!_function.isConstructor())
if (_function.isFallback())
m_context.adjustStackOffset(static_cast<int>(parametersSize));
else if (!_function.isConstructor())
// adding 1 for return address.
m_context.adjustStackOffset(static_cast<int>(parametersSize) + 1);
for (ASTPointer<VariableDeclaration> const& variable: _function.parameters())
@ -609,7 +623,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function)
}
for (ASTPointer<VariableDeclaration> const& variable: _function.returnParameters())
appendStackVariableInitialisation(*variable);
appendStackVariableInitialisation(*variable, /* _provideDefaultValue = */ true);
if (_function.isConstructor())
if (auto c = dynamic_cast<ContractDefinition const&>(*_function.scope()).nextConstructor(
@ -639,7 +653,8 @@ bool ContractCompiler::visit(FunctionDefinition const& _function)
unsigned const c_returnValuesSize = CompilerUtils::sizeOnStack(_function.returnParameters());
vector<int> stackLayout;
stackLayout.push_back(static_cast<int>(c_returnValuesSize)); // target of return address
if (!_function.isConstructor() && !_function.isFallback())
stackLayout.push_back(static_cast<int>(c_returnValuesSize)); // target of return address
stackLayout += vector<int>(c_argumentsSize, -1); // discard all arguments
for (size_t i = 0; i < c_returnValuesSize; ++i)
stackLayout.push_back(static_cast<int>(i));
@ -650,7 +665,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function)
errinfo_sourceLocation(_function.location()) <<
errinfo_comment("Stack too deep, try removing local variables.")
);
while (stackLayout.back() != static_cast<int>(stackLayout.size() - 1))
while (!stackLayout.empty() && stackLayout.back() != static_cast<int>(stackLayout.size() - 1))
if (stackLayout.back() < 0)
{
m_context << Instruction::POP;
@ -1226,7 +1241,7 @@ bool ContractCompiler::visit(VariableDeclarationStatement const& _variableDeclar
// and freed in the end of their scope.
for (auto decl: _variableDeclarationStatement.declarations())
if (decl)
appendStackVariableInitialisation(*decl);
appendStackVariableInitialisation(*decl, !_variableDeclarationStatement.initialValue());
StackHeightChecker checker(m_context);
if (Expression const* expression = _variableDeclarationStatement.initialValue())
@ -1391,11 +1406,20 @@ void ContractCompiler::appendModifierOrFunctionCode()
m_context.setModifierDepth(m_modifierDepth);
}
void ContractCompiler::appendStackVariableInitialisation(VariableDeclaration const& _variable)
void ContractCompiler::appendStackVariableInitialisation(
VariableDeclaration const& _variable,
bool _provideDefaultValue
)
{
CompilerContext::LocationSetter location(m_context, _variable);
m_context.addVariable(_variable);
CompilerUtils(m_context).pushZeroValue(*_variable.annotation().type);
if (!_provideDefaultValue && _variable.type()->dataStoredIn(DataLocation::Memory))
{
solAssert(_variable.type()->sizeOnStack() == 1, "");
m_context << u256(0);
}
else
CompilerUtils(m_context).pushZeroValue(*_variable.annotation().type);
}
void ContractCompiler::compileExpression(Expression const& _expression, TypePointer const& _targetType)

View File

@ -130,7 +130,10 @@ private:
/// body itself if the last modifier was reached.
void appendModifierOrFunctionCode();
void appendStackVariableInitialisation(VariableDeclaration const& _variable);
/// Creates a stack slot for the given variable and assigns a default value.
/// If the default value is complex (needs memory allocation) and @a _provideDefaultValue
/// is false, this might be skipped.
void appendStackVariableInitialisation(VariableDeclaration const& _variable, bool _provideDefaultValue);
void compileExpression(Expression const& _expression, TypePointer const& _targetType = TypePointer());
/// Frees the variables of a certain scope (to be used when leaving).

View File

@ -3090,14 +3090,16 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
solUnimplementedAssert(fromStructType.location() != DataLocation::Memory, "");
if (fromStructType.location() == DataLocation::CallData)
{
solUnimplementedAssert(!fromStructType.isDynamicallyEncoded(), "");
body = Whiskers(R"(
converted := <abiDecode>(value, calldatasize())
)")("abiDecode", ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector).tupleDecoder(
{&toStructType}
)).render();
}
)")
(
"abiDecode",
ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector).abiDecodingFunctionStruct(
toStructType,
false
)
).render();
else
{
solAssert(fromStructType.location() == DataLocation::Storage, "");

View File

@ -652,8 +652,16 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
{
string fallbackCode;
if (!fallback->isPayable())
fallbackCode += callValueCheck();
fallbackCode += m_context.enqueueFunctionForCodeGeneration(*fallback) + "() stop()";
fallbackCode += callValueCheck() + "\n";
if (fallback->parameters().empty())
fallbackCode += m_context.enqueueFunctionForCodeGeneration(*fallback) + "() stop()";
else
{
solAssert(fallback->parameters().size() == 1 && fallback->returnParameters().size() == 1, "");
fallbackCode += "let retval := " + m_context.enqueueFunctionForCodeGeneration(*fallback) + "(0, calldatasize())\n";
fallbackCode += "return(add(retval, 0x20), mload(retval))\n";
}
t("fallback", fallbackCode);
}

View File

@ -1119,7 +1119,7 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess)
}
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
// at all usable in the SMT checker currently
m_errorReporter.warning(
7507_error,
_memberAccess.location(),

View File

@ -28,18 +28,14 @@
set -e
REPO_ROOT="$(dirname "$0")"/../..
cd "$REPO_ROOT"
REPO_ROOT=$(pwd) # make it absolute
if test -z "$1"; then
BUILD_DIR="build"
else
BUILD_DIR="$1"
fi
BUILD_DIR="${1:-${REPO_ROOT}/build}"
echo "Compiling all test contracts into bytecode..."
TMPDIR=$(mktemp -d)
(
cd "$REPO_ROOT"
REPO_ROOT=$(pwd) # make it absolute
cd "$TMPDIR"
"$REPO_ROOT"/scripts/isolate_tests.py "$REPO_ROOT"/test/
@ -108,10 +104,10 @@ EOF
./solc *.sol > report.txt
echo "Finished running the compiler."
else
$REPO_ROOT/scripts/bytecodecompare/prepare_report.py $REPO_ROOT/$BUILD_DIR/solc/solc
"$REPO_ROOT/scripts/bytecodecompare/prepare_report.py" "$BUILD_DIR/solc/solc"
fi
cp report.txt $REPO_ROOT
cp report.txt "$REPO_ROOT"
)
rm -rf "$TMPDIR"
echo "Storebytecode finished."

View File

@ -55,6 +55,7 @@
#include <libsolutil/CommonIO.h>
#include <libsolutil/JSON.h>
#include <algorithm>
#include <memory>
#include <boost/filesystem.hpp>
@ -1780,20 +1781,26 @@ bool CommandLineInterface::link()
{
while (it != end && *it != '_') ++it;
if (it == end) break;
if (end - it < placeholderSize)
if (
end - it < placeholderSize ||
*(it + 1) != '_' ||
*(it + placeholderSize - 2) != '_' ||
*(it + placeholderSize - 1) != '_'
)
{
serr() << "Error in binary object file " << src.first << " at position " << (end - src.second.begin()) << endl;
serr() << "Error in binary object file " << src.first << " at position " << (it - src.second.begin()) << endl;
serr() << '"' << string(it, it + min(placeholderSize, static_cast<int>(end - it))) << "\" is not a valid link reference." << endl;
return false;
}
string name(it, it + placeholderSize);
if (librariesReplacements.count(name))
string foundPlaceholder(it, it + placeholderSize);
if (librariesReplacements.count(foundPlaceholder))
{
string hexStr(toHex(librariesReplacements.at(name).asBytes()));
string hexStr(toHex(librariesReplacements.at(foundPlaceholder).asBytes()));
copy(hexStr.begin(), hexStr.end(), it);
}
else
serr() << "Reference \"" << name << "\" in file \"" << src.first << "\" still unresolved." << endl;
serr() << "Reference \"" << foundPlaceholder << "\" in file \"" << src.first << "\" still unresolved." << endl;
it += placeholderSize;
}
// Remove hints for resolved libraries.

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { uint x; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint[] calldata) pure external {}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
pragma experimental ABIEncoderV2;
pragma abicoder v2;
// The point of this test is to check that the
// AST IDs are removed from the optimized IR

View File

@ -2,7 +2,7 @@
"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) { } }"
"content": "// SPDX-License-Identifier: GPL-3.0\npragma abicoder v2; contract A { function f(uint[] memory) public view returns (uint256) { } }"
}
},
"settings": {

View File

@ -84,5 +84,9 @@
}
}
<<<<<<< HEAD
","id":1,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"<BYTECODE REMOVED>","opcodes":"<OPCODES REMOVED>","sourceMap":"70:74:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83:59;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;130:7;83:59;;;:::o;24:622:1:-;;145:80;160:64;217:6;160:64;:::i;:::-;145:80;:::i;:::-;136:89;;245:5;273:6;266:5;259:21;299:4;292:5;288:16;281:23;;324:6;374:3;366:4;358:6;354:17;349:3;345:27;342:36;339:2;;;391:1;388;381:12;339:2;419:1;404:236;429:6;426:1;423:13;404:236;;;496:3;524:37;557:3;545:10;524:37;:::i;:::-;519:3;512:50;591:4;586:3;582:14;575:21;;625:4;620:3;616:14;609:21;;464:176;451:1;448;444:9;439:14;;404:236;;;408:14;126:520;;;;;;;:::o;669:303::-;;789:3;782:4;774:6;770:17;766:27;756:2;;807:1;804;797:12;756:2;847:6;834:20;872:94;962:3;954:6;947:4;939:6;935:17;872:94;:::i;:::-;863:103;;746:226;;;;;:::o;978:139::-;;1062:6;1049:20;1040:29;;1078:33;1105:5;1078:33;:::i;:::-;1030:87;;;;:::o;1123:403::-;;1256:2;1244:9;1235:7;1231:23;1227:32;1224:2;;;1272:1;1269;1262:12;1224:2;1342:1;1331:9;1327:17;1314:31;1372:18;1364:6;1361:30;1358:2;;;1404:1;1401;1394:12;1358:2;1431:78;1501:7;1492:6;1481:9;1477:22;1431:78;:::i;:::-;1421:88;;1286:233;1214:312;;;;:::o;1532:118::-;1619:24;1637:5;1619:24;:::i;:::-;1614:3;1607:37;1597:53;;:::o;1656:222::-;;1787:2;1776:9;1772:18;1764:26;;1800:71;1868:1;1857:9;1853:17;1844:6;1800:71;:::i;:::-;1754:124;;;;:::o;1884:283::-;;1950:2;1944:9;1934:19;;1992:4;1984:6;1980:17;2099:6;2087:10;2084:22;2063:18;2051:10;2048:34;2045:62;2042:2;;;2110:18;;:::i;:::-;2042:2;2150:10;2146:2;2139:22;1924:243;;;;:::o;2173:311::-;;2340:18;2332:6;2329:30;2326:2;;;2362:18;;:::i;:::-;2326:2;2412:4;2404:6;2400:17;2392:25;;2472:4;2466;2462:15;2454:23;;2255:229;;;:::o;2490:77::-;;2556:5;2545:16;;2535:32;;;:::o;2573:180::-;2621:77;2618:1;2611:88;2718:4;2715:1;2708:15;2742:4;2739:1;2732:15;2759:122;2832:24;2850:5;2832:24;:::i;:::-;2825:5;2822:35;2812:2;;2871:1;2868;2861:12;2812:2;2802:79;:::o"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
=======
","id":1,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"<BYTECODE REMOVED>","opcodes":"<OPCODES REMOVED>","sourceMap":"56:74:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69:59;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;116:7;69:59;;;:::o;24:622:1:-;;145:80;160:64;217:6;160:64;:::i;:::-;145:80;:::i;:::-;136:89;;245:5;273:6;266:5;259:21;299:4;292:5;288:16;281:23;;324:6;374:3;366:4;358:6;354:17;349:3;345:27;342:36;339:2;;;391:1;388;381:12;339:2;419:1;404:236;429:6;426:1;423:13;404:236;;;496:3;524:37;557:3;545:10;524:37;:::i;:::-;519:3;512:50;591:4;586:3;582:14;575:21;;625:4;620:3;616:14;609:21;;464:176;451:1;448;444:9;439:14;;404:236;;;408:14;126:520;;;;;;;:::o;669:303::-;;789:3;782:4;774:6;770:17;766:27;756:2;;807:1;804;797:12;756:2;847:6;834:20;872:94;962:3;954:6;947:4;939:6;935:17;872:94;:::i;:::-;863:103;;746:226;;;;;:::o;978:139::-;;1062:6;1049:20;1040:29;;1078:33;1105:5;1078:33;:::i;:::-;1030:87;;;;:::o;1123:403::-;;1256:2;1244:9;1235:7;1231:23;1227:32;1224:2;;;1272:1;1269;1262:12;1224:2;1342:1;1331:9;1327:17;1314:31;1372:18;1364:6;1361:30;1358:2;;;1404:1;1401;1394:12;1358:2;1431:78;1501:7;1492:6;1481:9;1477:22;1431:78;:::i;:::-;1421:88;;1286:233;1214:312;;;;:::o;1532:118::-;1619:24;1637:5;1619:24;:::i;:::-;1614:3;1607:37;1597:53;;:::o;1656:222::-;;1787:2;1776:9;1772:18;1764:26;;1800:71;1868:1;1857:9;1853:17;1844:6;1800:71;:::i;:::-;1754:124;;;;:::o;1884:278::-;;1950:2;1944:9;1934:19;;1992:4;1984:6;1980:17;2099:6;2087:10;2084:22;2063:18;2051:10;2048:34;2045:62;2042:2;;;2110:13;;:::i;:::-;2042:2;2145:10;2141:2;2134:22;1924:238;;;;:::o;2168:306::-;;2335:18;2327:6;2324:30;2321:2;;;2357:13;;:::i;:::-;2321:2;2402:4;2394:6;2390:17;2382:25;;2462:4;2456;2452:15;2444:23;;2250:224;;;:::o;2480:77::-;;2546:5;2535:16;;2525:32;;;:::o;2563:48::-;2596:9;2617:122;2690:24;2708:5;2690:24;:::i;:::-;2683:5;2680:35;2670:2;;2729:1;2726;2719:12;2670:2;2660:79;:::o"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
>>>>>>> origin/develop
","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}}}

View File

@ -2,7 +2,7 @@
"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) { } }"
"content": "// SPDX-License-Identifier: GPL-3.0\npragma abicoder v2; contract A { function f(uint[] memory) public view returns (uint256) { } }"
}
},
"settings": {

View File

@ -35,6 +35,7 @@
tail := add(headStart, 32)
mstore(headStart, value0)
}
<<<<<<< HEAD
function panic_error_0x41()
{
mstore(0, shl(224, 0x4e487b71))
@ -42,4 +43,7 @@
revert(0, 0x24)
}
}","id":1,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"<BYTECODE REMOVED>","opcodes":"<OPCODES REMOVED>","sourceMap":"70:74:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83:59;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;130:7:0;;83:59::o;14:1158:1:-;;129:2;172;160:9;151:7;147:23;143:32;140:2;;;193:6;185;178:22;140:2;238:9;225:23;267:18;308:2;300:6;297:14;294:2;;;329:6;321;314:22;294:2;372:6;361:9;357:22;347:32;;417:7;410:4;406:2;402:13;398:27;388:2;;444:6;436;429:22;388:2;485;472:16;507:2;503;500:10;497:2;;;513:18;;:::i;:::-;560:2;556;552:11;592:2;586:9;643:2;638;630:6;626:15;622:24;696:6;684:10;681:22;676:2;664:10;661:18;658:46;655:2;;;707:18;;:::i;:::-;743:2;736:22;793:18;;;827:15;;;;-1:-1:-1;862:11:1;;;892;;;888:20;;885:33;-1:-1:-1;882:2:1;;;936:6;928;921:22;882:2;963:6;954:15;;978:163;992:2;989:1;986:9;978:163;;;1049:17;;1037:30;;1010:1;1003:9;;;;;1087:12;;;;1119;;978:163;;;-1:-1:-1;1160:6:1;109:1063;-1:-1:-1;;;;;;;;109:1063:1:o;1177:177::-;1323:25;;;1311:2;1296:18;;1278:76::o;1359:127::-;1420:10;1415:3;1411:20;1408:1;1401:31;1451:4;1448:1;1441:15;1475:4;1472:1;1465:15"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
=======
}","id":1,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"<BYTECODE REMOVED>","opcodes":"<OPCODES REMOVED>","sourceMap":"56:74:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69:59;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;116:7:0;;69:59::o;14:1140:1:-;;129:2;172;160:9;151:7;147:23;143:32;140:2;;;193:6;185;178:22;140:2;238:9;225:23;267:18;308:2;300:6;297:14;294:2;;;329:6;321;314:22;294:2;372:6;361:9;357:22;347:32;;417:7;410:4;406:2;402:13;398:27;388:2;;444:6;436;429:22;388:2;485;472:16;507:2;503;500:10;497:2;;;513:9;497:2;551;547;543:11;583:2;577:9;634:2;629;621:6;617:15;613:24;687:6;675:10;672:22;667:2;655:10;652:18;649:46;646:2;;;698:9;646:2;725;718:22;775:18;;;809:15;;;;-1:-1:-1;844:11:1;;;874;;;870:20;;867:33;-1:-1:-1;864:2:1;;;918:6;910;903:22;864:2;945:6;936:15;;960:163;974:2;971:1;968:9;960:163;;;1031:17;;1019:30;;992:1;985:9;;;;;1069:12;;;;1101;;960:163;;;-1:-1:-1;1142:6:1;109:1045;-1:-1:-1;;;;;;;;109:1045:1:o;1159:177::-;1305:25;;;1293:2;1278:18;;1260:76::o"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
>>>>>>> origin/develop
","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}}}

View File

@ -180,14 +180,14 @@ function force_solc_settings
function force_abi_v2
{
# Add "pragma experimental ABIEncoderV2" to all files.
printLog "Forcibly enabling ABIEncoderV2..."
# Add "pragma abi coder v2" to all files.
printLog "Forcibly enabling abi coder v2..."
find contracts test -name '*.sol' -type f -print0 | \
while IFS= read -r -d '' file
do
# Only add the pragma if it is not already there.
if grep -q -v 'pragma experimental ABIEncoderV2' "$file"; then
sed -i -e '1 i pragma experimental ABIEncoderV2;' "$file"
if grep -q -v 'pragma abicoder v2' "$file"; then
sed -i -e '1 i pragma abicoder v2;' "$file"
fi
done
}
@ -257,7 +257,7 @@ function truffle_run_test
do
clean
force_solc_settings "$CONFIG" "$optimize" "istanbul"
# Force ABIEncoderV2 in the last step. Has to be the last because code is modified.
# Force abi coder v2 in the last step. Has to be the last because code is modified.
if [ "$FORCE_ABIv2" = true ]; then
[[ "$optimize" =~ yul ]] && force_abi_v2
fi

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { uint a; T[] sub; bytes b; }
struct T { uint[2] x; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
struct S { uint a; }
contract C {
function f(S calldata s) external view {}

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { uint a; T[] sub; }
struct T { uint[2] x; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { C[] x; C y; }
function f() public returns (S memory s, C c) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
library L {
struct S { uint a; T[] sub; bytes b; }
struct T { uint[2] x; }

View File

@ -1890,7 +1890,7 @@ BOOST_AUTO_TEST_CASE(event_really_really_lots_of_data_from_storage)
BOOST_AUTO_TEST_CASE(event_struct_memory_v2)
{
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { uint a; }
event E(S);
@ -1912,7 +1912,7 @@ BOOST_AUTO_TEST_CASE(event_struct_memory_v2)
BOOST_AUTO_TEST_CASE(event_struct_storage_v2)
{
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { uint a; }
event E(S);
@ -1960,7 +1960,7 @@ BOOST_AUTO_TEST_CASE(event_dynamic_array_memory)
BOOST_AUTO_TEST_CASE(event_dynamic_array_memory_v2)
{
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
event E(uint[]);
function createEvent(uint x) public {
@ -1985,7 +1985,7 @@ BOOST_AUTO_TEST_CASE(event_dynamic_array_memory_v2)
BOOST_AUTO_TEST_CASE(event_dynamic_nested_array_memory_v2)
{
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
event E(uint[][]);
function createEvent(uint x) public {
@ -2043,7 +2043,7 @@ BOOST_AUTO_TEST_CASE(event_dynamic_array_storage)
BOOST_AUTO_TEST_CASE(event_dynamic_array_storage_v2)
{
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
event E(uint[]);
uint[] arr;
@ -2074,7 +2074,7 @@ BOOST_AUTO_TEST_CASE(event_dynamic_array_storage_v2)
BOOST_AUTO_TEST_CASE(event_dynamic_nested_array_storage_v2)
{
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
event E(uint[][]);
uint[][] arr;
@ -2239,7 +2239,7 @@ BOOST_AUTO_TEST_CASE(generic_delegatecall)
for (auto v2: {false, true})
{
string source = (v2 ? "pragma experimental ABIEncoderV2;\n" : "") + string(sourceCode);
string source = "pragma abicoder " + string(v2 ? "v2" : "v1") + ";\n" + string(sourceCode);
compileAndRun(source, 0, "Receiver");
u160 const c_receiverAddress = m_contractAddress;
@ -2567,7 +2567,7 @@ BOOST_AUTO_TEST_CASE(storing_invalid_boolean)
BOOST_AUTO_TEST_CASE(struct_referencing)
{
static char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
interface I {
struct S { uint a; }
}
@ -2710,7 +2710,7 @@ BOOST_AUTO_TEST_CASE(array_copy_storage_abi)
// NOTE: This does not really test copying from storage to ABI directly,
// because it will always copy to memory first.
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract c {
uint8[] x;
uint16[] y;
@ -3097,7 +3097,7 @@ BOOST_AUTO_TEST_CASE(memory_types_initialisation)
BOOST_AUTO_TEST_CASE(calldata_struct_short)
{
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { uint256 a; uint256 b; }
function f(S calldata) external pure returns (uint256) {
@ -3120,7 +3120,7 @@ BOOST_AUTO_TEST_CASE(calldata_struct_short)
BOOST_AUTO_TEST_CASE(calldata_struct_function_type)
{
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { function (uint) external returns (uint) fn; }
function f(S calldata s) external returns (uint256) {
@ -3169,7 +3169,7 @@ BOOST_AUTO_TEST_CASE(calldata_array_dynamic_three_dimensional)
arrayType += outerDynamicallySized ? "[]" : "[2]";
string sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function test()" + arrayType + R"( calldata a) external returns (uint256) {
return a.length;
@ -3768,7 +3768,7 @@ BOOST_AUTO_TEST_CASE(using_library_mappings_external)
)";
for (auto v2: {false, true})
{
string prefix = v2 ? "pragma experimental ABIEncoderV2;\n" : "";
string prefix = "pragma abicoder " + string(v2 ? "v2" : "v1") + ";\n";
compileAndRun(prefix + libSourceCode, 0, "Lib");
compileAndRun(prefix + sourceCode, 0, "Test", bytes(), map<string, Address>{{"Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(2), u256(0), u256(84), u256(46), u256(0), u256(198)));
@ -5040,7 +5040,8 @@ BOOST_AUTO_TEST_CASE(abi_encodePacked)
)";
for (auto v2: {false, true})
{
compileAndRun(string(v2 ? "pragma experimental ABIEncoderV2;\n" : "") + sourceCode, 0, "C");
string prefix = "pragma abicoder " + string(v2 ? "v2" : "v1") + ";\n";
compileAndRun(prefix + sourceCode, 0, "C");
ABI_CHECK(callContractFunction("f0()"), encodeArgs(0x20, 0));
ABI_CHECK(callContractFunction("f1()"), encodeArgs(0x20, 2, "\x01\x02"));
ABI_CHECK(callContractFunction("f2()"), encodeArgs(0x20, 5, "\x01" "abc" "\x02"));
@ -5114,7 +5115,8 @@ BOOST_AUTO_TEST_CASE(abi_encodePacked_from_storage)
)";
for (auto v2: {false, true})
{
compileAndRun(string(v2 ? "pragma experimental ABIEncoderV2;\n" : "") + sourceCode, 0, "C");
string prefix = "pragma abicoder " + string(v2 ? "v2" : "v1") + ";\n";
compileAndRun(prefix + sourceCode, 0, "C");
bytes payload = encodeArgs(0xfffff1, 0, 0xfffff2, 0, 0, 0xfffff3, 0, 0, 0xfffff4);
bytes encoded = encodeArgs(0x20, 0x122, "\x01" + asString(payload) + "\x02");
ABI_CHECK(callContractFunction("sf()"), encoded);
@ -5184,7 +5186,8 @@ BOOST_AUTO_TEST_CASE(abi_encodePacked_from_memory)
)";
for (auto v2: {false, true})
{
compileAndRun(string(v2 ? "pragma experimental ABIEncoderV2;\n" : "") + sourceCode, 0, "C");
string prefix = "pragma abicoder " + string(v2 ? "v2" : "v1") + ";\n";
compileAndRun(prefix + sourceCode, 0, "C");
bytes payload = encodeArgs(0xfffff1, 0, 0xfffff2, 0, 0, 0xfffff3, 0, 0, 0xfffff4);
bytes encoded = encodeArgs(0x20, 0x122, "\x01" + asString(payload) + "\x02");
ABI_CHECK(callContractFunction("sf()"), encoded);
@ -5227,7 +5230,8 @@ BOOST_AUTO_TEST_CASE(abi_encodePacked_functionPtr)
)";
for (auto v2: {false, true})
{
compileAndRun(string(v2 ? "pragma experimental ABIEncoderV2;\n" : "") + sourceCode, 0, "C");
string prefix = "pragma abicoder " + string(v2 ? "v2" : "v1") + ";\n";
compileAndRun(prefix + sourceCode, 0, "C");
string directEncoding = asString(fromHex("08" "1112131400000000000011121314000000000087" "26121ff0" "02"));
ABI_CHECK(callContractFunction("testDirect()"), encodeArgs(0x20, directEncoding.size(), directEncoding));
string arrayEncoding = asString(fromHex("08" "1112131400000000000011121314000000000087" "26121ff0" "0000000000000000" "02"));
@ -5239,7 +5243,7 @@ BOOST_AUTO_TEST_CASE(abi_encodePacked_functionPtr)
BOOST_AUTO_TEST_CASE(abi_encodePackedV2_structs)
{
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S {
uint8 a;
@ -5281,7 +5285,7 @@ BOOST_AUTO_TEST_CASE(abi_encodePackedV2_structs)
BOOST_AUTO_TEST_CASE(abi_encodePackedV2_nestedArray)
{
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S {
uint8 a;
@ -5310,7 +5314,7 @@ BOOST_AUTO_TEST_CASE(abi_encodePackedV2_nestedArray)
BOOST_AUTO_TEST_CASE(abi_encodePackedV2_arrayOfStrings)
{
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
string[] x;
event E(string[] indexed);
@ -5344,7 +5348,7 @@ BOOST_AUTO_TEST_CASE(event_signature_in_library)
// This tests a bug that was present where the "internal signature"
// for structs was also used for events.
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
library L {
struct S {
uint8 a;
@ -5401,7 +5405,7 @@ BOOST_AUTO_TEST_CASE(abi_encode_with_selector)
BOOST_AUTO_TEST_CASE(abi_encode_with_selectorv2)
{
char const* sourceCode = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f0() public pure returns (bytes memory) {
return abi.encodeWithSelector(0x12345678);
@ -5491,7 +5495,7 @@ BOOST_AUTO_TEST_CASE(abi_encode_with_signature)
BOOST_AUTO_TEST_CASE(abi_encode_with_signaturev2)
{
char const* sourceCode = R"T(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f0() public pure returns (bytes memory) {
return abi.encodeWithSignature("f(uint256)");

View File

@ -132,11 +132,12 @@ bytes SolidityExecutionFramework::compileContract(
string SolidityExecutionFramework::addPreamble(string const& _sourceCode)
{
// Silence compiler version warning
string preamble = "pragma solidity >=0.0;\n";
string preamble = "pragma solidity >=0.0;\n// SPDX-License-Identifier: unlicensed\n";
if (
solidity::test::CommonOptions::get().useABIEncoderV2 &&
_sourceCode.find("pragma experimental ABIEncoderV2;") == string::npos
_sourceCode.find("pragma experimental ABIEncoderV2;") == string::npos &&
_sourceCode.find("pragma abicoder") == string::npos
)
preamble += "pragma experimental ABIEncoderV2;\n";
preamble += "pragma abicoder v2;\n";
return preamble + _sourceCode;
}

View File

@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE(enum_external_type)
BOOST_AUTO_TEST_CASE(external_struct_signatures)
{
char const* text = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract Test {
enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
struct Simple { uint i; }
@ -228,7 +228,7 @@ BOOST_AUTO_TEST_CASE(external_struct_signatures)
BOOST_AUTO_TEST_CASE(external_struct_signatures_in_libraries)
{
char const* text = R"(
pragma experimental ABIEncoderV2;
pragma abicoder v2;
library Test {
enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
struct Simple { uint i; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
uint public a;

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
uint public a;

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function exp_neg_one(uint exponent) public returns(int) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function exp_neg_one(uint exponent) public returns(int) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function enc_packed_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {
return abi.encodePacked(data[start:end]);

View File

@ -1,6 +1,6 @@
// Tests that this will not end up using a "bytes0" type
// (which would assert)
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {

View File

@ -1,5 +1,5 @@
// Tests that rational numbers (even negative ones) are encoded properly.
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {

View File

@ -1,5 +1,5 @@
==== Source: A ====
pragma experimental ABIEncoderV2;
pragma abicoder v2;
struct Data {
uint a;

View File

@ -1,5 +1,5 @@
==== Source: A ====
pragma experimental ABIEncoderV2;
pragma abicoder v2;
struct Data {
uint value;

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(bool b) public pure returns (bool) { return b; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint a, bytes memory b, uint c)

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function g(uint256[] calldata) external pure returns (bytes memory) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint256[] calldata s) external pure returns (bytes memory) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint256[] calldata s) external pure returns (bytes memory) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint8[][1][] calldata s) external pure returns (bytes memory) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint256[][2][] calldata x) external returns (uint256) {
x[0]; // trigger bounds checks

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint256[][2][] calldata x) external returns (uint256) {
return 42;

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint256[][] calldata s) external pure returns (bytes memory) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint256[3] calldata s) external pure returns (bytes memory) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint256[3] calldata s) external pure returns (bytes memory) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { uint256[] a; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { uint256[] a; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct A {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { uint256 a; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function g(address x) external pure returns (uint256 r) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function gggg(bool x) external pure returns (bool) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function gg1(bytes1 x) external pure returns (bytes32) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint16 a, int16 b, address c, bytes3 d, bool e)

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function ggg(uint8[] calldata s) external pure returns (bytes memory) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { function() external f; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function ggg8(int8 x) external pure returns (int256) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { uint8 a; bytes1 b; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function gggggggg(uint8[2] calldata s) external pure returns (bytes memory) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function ggg8(uint8 x) external pure returns (uint256) {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint a, uint16[] memory b, uint c)

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d)

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
enum E { A, B }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(bytes memory a, bytes calldata b, uint[] memory c)

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
// tests encoding from storage arrays

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { C c; uint[] x; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { C c; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { function () external returns (uint) f; uint b; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { int a; uint b; bytes16 c; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { uint a; uint8 b; uint8 c; bytes2 d; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { int16 a; uint8 b; bytes2 c; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S { function () external x; }

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(bytes calldata x) public returns (C[] memory) {
return abi.decode(x, (C[]));

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function test(uint256[][2] calldata a) external returns (uint256) {
return a.length;

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function test(uint256[][] calldata a) external returns (uint256) {
return a.length;

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
function f(bytes[] calldata a, uint256 i) external returns (uint) {
return uint8(a[0][i]);

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract c {
uint256[][] a1;

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
struct S {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {
uint256[] s;

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {

View File

@ -1,4 +1,4 @@
pragma experimental ABIEncoderV2;
pragma abicoder v2;
contract C {

Some files were not shown because too many files have changed in this diff Show More