aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md9
-rw-r--r--.github/ISSUE_TEMPLATE/feature_request.md12
-rw-r--r--.github/ISSUE_TEMPLATE/general.md6
-rw-r--r--.github/PULL_REQUEST_TEMPLATE.md6
-rw-r--r--Changelog.md1
-rw-r--r--docs/assembly.rst8
-rw-r--r--docs/contracts.rst4
-rw-r--r--docs/layout-of-source-files.rst2
-rw-r--r--docs/security-considerations.rst41
-rw-r--r--docs/yul.rst9
-rw-r--r--libevmasm/GasMeter.cpp3
-rw-r--r--libevmasm/Instruction.cpp2
-rw-r--r--libevmasm/Instruction.h1
-rw-r--r--libevmasm/SemanticInformation.cpp3
-rw-r--r--libjulia/optimiser/FullInliner.cpp5
-rw-r--r--libsolidity/ast/AST.cpp6
-rw-r--r--libsolidity/ast/ASTJsonConverter.cpp9
-rw-r--r--libsolidity/codegen/ArrayUtils.cpp2
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp9
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp2
-rw-r--r--libsolidity/formal/SMTChecker.cpp2
-rw-r--r--libsolidity/formal/Z3Interface.cpp2
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.cpp12
-rw-r--r--libsolidity/interface/CompilerStack.cpp3
-rw-r--r--libsolidity/interface/Exceptions.cpp3
-rwxr-xr-xscripts/tests.sh10
-rwxr-xr-xtest/cmdlineTests.sh10
-rw-r--r--test/libjulia/Inliner.cpp35
-rw-r--r--test/liblll/Compiler.cpp4
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp13
-rw-r--r--test/tools/fuzzer.cpp71
31 files changed, 202 insertions, 103 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 0cc0edec..c3caf86e 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -3,7 +3,7 @@ name: Bug Report
about: Bug reports about the Solidity Compiler.
---
-## Prerequisites
+<!--## Prerequisites
- First, many thanks for taking part in the community. We really appreciate that.
- We realize there is a lot of information requested here. We ask only that you do your best to provide as much information as possible so we can better help you.
@@ -12,12 +12,11 @@ about: Bug reports about the Solidity Compiler.
- [Stack Overflow](https://ethereum.stackexchange.com/)
- Ensure the issue isn't already reported.
- The issue should be reproducible with the latest solidity version; however, this isn't a hard requirement and being reproducible with an older version is sufficient.
-
-*Delete the above section and the instructions in the sections below before submitting*
+-->
## Description
-Please shortly describe the bug you have found, and what you expect instead.
+<!--Please shortly describe the bug you have found, and what you expect instead.-->
## Environment
@@ -28,6 +27,7 @@ Please shortly describe the bug you have found, and what you expect instead.
## Steps to Reproduce
+<!--
Please provide a *minimal* source code example to trigger the bug you have found.
Please also mention any command line flags that are necessary for triggering the bug.
Provide as much information as necessary to reproduce the bug.
@@ -36,3 +36,4 @@ Provide as much information as necessary to reproduce the bug.
// Some *minimal* Solidity source code to reproduce the bug.
// ...
```
+--> \ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 6b98fb99..6702b62c 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -3,7 +3,7 @@ name: Feature Request
about: Solidity language or infrastructure feature requests.
---
-## Prerequisites
+<!--## Prerequisites
- First, many thanks for taking part in the community. We really appreciate that.
- We realize there is a lot of data requested here. We ask only that you do your best to provide as much information as possible so we can better help you.
@@ -14,24 +14,34 @@ about: Solidity language or infrastructure feature requests.
*Delete the above section and the instructions in the sections below before submitting*
+-->
+
## Abstract
+<!--
Please describe by example what problem you see in the current Solidity language
and reason about it.
+-->
## Motivation
+<!--
In this section you describe how you propose to address the problem you described earlier,
including by giving one or more exemplary source code snippets for demonstration.
+-->
## Specification
+<!--
The technical specification should describe the syntax and semantics of any new feature. The
specification should be detailed enough to allow any developer to implement the functionality.
+-->
## Backwards Compatibility
+<!--
All language changes that introduce backwards incompatibilities must include a section describing
these incompatibilities and their severity.
Please describe how you propose to deal with these incompatibilities.
+--> \ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/general.md b/.github/ISSUE_TEMPLATE/general.md
index 2d277865..410b42e0 100644
--- a/.github/ISSUE_TEMPLATE/general.md
+++ b/.github/ISSUE_TEMPLATE/general.md
@@ -3,7 +3,7 @@ name: General Feedback
about: Any general feedback (neither feature request nor bug reports)
---
-## Prerequisites
+<!--## Prerequisites
- First, many thanks for taking part in the community. We really appreciate that.
- Read the [contributing guidelines](http://solidity.readthedocs.io/en/latest/contributing.html).
@@ -13,7 +13,9 @@ about: Any general feedback (neither feature request nor bug reports)
- Ensure the issue isn't already reported.
*Delete the above section and the instructions in the sections below before submitting*
-
+-->
## Description
+<!--
Please describe the purpose of your ticket.
+-->
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 6f544bc1..9734fe81 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,8 +1,9 @@
-### Your checklist for this pull request
+<!--### Your checklist for this pull request
Please review the [guidelines for contributing](http://solidity.readthedocs.io/en/latest/contributing.html) to this repository.
Please also note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). By participating in this project you agree to abide by its terms.
+-->
### Checklist
- [ ] Code compiles correctly
@@ -13,6 +14,9 @@ Please also note that this project is released with a [Contributor Code of Condu
- [ ] Used meaningful commit messages
### Description
+
+<!--
Please explain the changes you made here.
Thank you for your help!
+--> \ No newline at end of file
diff --git a/Changelog.md b/Changelog.md
index 7330f6d3..fbb41ece 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -91,6 +91,7 @@ Compiler Features:
* Build System: Support for Mojave version of macOS added.
* C API (``libsolc``): Export the ``solidity_license``, ``solidity_version`` and ``solidity_compile`` methods.
* Code Generator: ``CREATE2`` instruction has been updated to match EIP1014 (aka "Skinny CREATE2"). It also is accepted as part of Constantinople.
+ * Code Generator: ``EXTCODEHASH`` instruction has been added based on EIP1052.
* Type Checker: Nicer error message when trying to reference overloaded identifiers in inline assembly.
* Type Checker: Show named argument in case of error.
* Type System: IntegerType is split into IntegerType and AddressType internally.
diff --git a/docs/assembly.rst b/docs/assembly.rst
index 5d723645..c609fa9d 100644
--- a/docs/assembly.rst
+++ b/docs/assembly.rst
@@ -271,12 +271,16 @@ In the grammar, opcodes are represented as pre-defined identifiers.
+-------------------------+-----+---+-----------------------------------------------------------------+
| returndatacopy(t, f, s) | `-` | B | copy s bytes from returndata at position f to mem at position t |
+-------------------------+-----+---+-----------------------------------------------------------------+
+| extcodehash(a) | | C | code hash of address a |
++-------------------------+-----+---+-----------------------------------------------------------------+
| create(v, p, s) | | F | create new contract with code mem[p...(p+s)) and send v wei |
| | | | and return the new address |
+-------------------------+-----+---+-----------------------------------------------------------------+
| create2(v, n, p, s) | | C | create new contract with code mem[p...(p+s)) at address |
-| | | | keccak256(<address> . n . keccak256(mem[p...(p+s))) and send v |
-| | | | wei and return the new address |
+| | | | keccak256(0xff . self . n . keccak256(mem[p...(p+s))) |
+| | | | and send v wei and return the new address, where ``0xff`` is a |
+| | | | 8 byte value, ``self`` is the current contract's address |
+| | | | as a 20 byte value and ``n`` is a big-endian 256-bit value |
+-------------------------+-----+---+-----------------------------------------------------------------+
| call(g, a, v, in, | | F | call contract at address a with input mem[in...(in+insize)) |
| insize, out, outsize) | | | providing g gas and v wei and output area |
diff --git a/docs/contracts.rst b/docs/contracts.rst
index 315d1815..93f54e4a 100644
--- a/docs/contracts.rst
+++ b/docs/contracts.rst
@@ -1131,7 +1131,7 @@ Multiple Inheritance and Linearization
Languages that allow multiple inheritance have to deal with
several problems. One is the `Diamond Problem <https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem>`_.
Solidity is similar to Python in that it uses "`C3 Linearization <https://en.wikipedia.org/wiki/C3_linearization>`_"
-to force a specific order in the directed acyclic graph of base classes. This
+to force a specific order in the directed acyclic graph (DAG) of base classes. This
results in the desirable property of monotonicity but
disallows some inheritance graphs. Especially, the order in
which the base classes are given in the ``is`` directive is
@@ -1295,7 +1295,7 @@ contract, and a regular ``JUMP`` call will be used instead of a ``DELEGATECALL``
.. index:: using for, set
-The following example illustrates how to use libraries (butmanual method
+The following example illustrates how to use libraries (but manual method
be sure to check out :ref:`using for <using-for>` for a
more advanced example to implement a set).
diff --git a/docs/layout-of-source-files.rst b/docs/layout-of-source-files.rst
index d89ecded..fb18f8a9 100644
--- a/docs/layout-of-source-files.rst
+++ b/docs/layout-of-source-files.rst
@@ -77,6 +77,8 @@ for this part of the code is still under development) and has not
received as much testing as the old encoder. You can activate it
using ``pragma experimental ABIEncoderV2;``.
+.. _smt_checker:
+
SMTChecker
~~~~~~~~~~
diff --git a/docs/security-considerations.rst b/docs/security-considerations.rst
index 3305c1e1..bd06276b 100644
--- a/docs/security-considerations.rst
+++ b/docs/security-considerations.rst
@@ -136,15 +136,16 @@ Sending and Receiving Ether
- If a contract receives Ether (without a function being called), the fallback function is executed.
If it does not have a fallback function, the Ether will be rejected (by throwing an exception).
During the execution of the fallback function, the contract can only rely
- on the "gas stipend" it is passed (2300 gas) being available to it at that time. This stipend is not enough to access storage in any way.
+ on the "gas stipend" it is passed (2300 gas) being available to it at that time. This stipend is not enough to modify storage
+ (do not take this for granted though, the stipend might change with future hard forks).
To be sure that your contract can receive Ether in that way, check the gas requirements of the fallback function
(for example in the "details" section in Remix).
- There is a way to forward more gas to the receiving contract using
``addr.call.value(x)("")``. This is essentially the same as ``addr.transfer(x)``,
only that it forwards all remaining gas and opens up the ability for the
- recipient to perform more expensive actions (and it only returns a failure code
- and does not automatically propagate the error). This might include calling back
+ recipient to perform more expensive actions (and it returns a failure code
+ instead of automatically propagating the error). This might include calling back
into the sending contract or other state changes you might not have thought of.
So it allows for great flexibility for honest users but also for malicious actors.
@@ -223,6 +224,26 @@ Now someone tricks you into sending ether to the address of this attack wallet:
If your wallet had checked ``msg.sender`` for authorization, it would get the address of the attack wallet, instead of the owner address. But by checking ``tx.origin``, it gets the original address that kicked off the transaction, which is still the owner address. The attack wallet instantly drains all your funds.
+
+Two's Complement / Underflows / Overflows
+=========================================
+
+As in many programming languages, Solidity's integer types are not actually integers.
+They resemble integers when the values are small, but behave differently if the numbers are larger.
+For example, the following is true: ``uint8(255) + uint8(1) == 0``. This situation is called
+an *overflow*. It occurs when an operation is performed that requires a fixed size variable
+to store a number (or piece of data) that is outside the range of the variable's data type.
+An *underflow* is the converse situation: ``uint8(0) - uint8(1) == 255``.
+
+In general, read about the limits of two's complement representation, which even has some
+more special edge cases for signed numbers.
+
+Try to use ``require`` to limit the size of inputs to a reasonable range and use the
+:ref:`SMT checker<smt_checker>` to find potential overflows, or
+use a library like
+`SafeMath<https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol>`
+if you want all overflows to cause a revert.
+
Minor Details
=============
@@ -246,12 +267,8 @@ implications, there might be another issue buried beneath it.
Any compiler warning we issue can be silenced by slight changes to the
code.
-Also try to enable the "0.5.0" safety features as early as possible
-by adding ``pragma experimental "v0.5.0";``. Note that in this case,
-the word ``experimental`` does not mean that the safety features are in any
-way risky, it is just a way to enable some features that are
-not yet part of the latest version of Solidity due to backwards
-compatibility.
+Always use the latest version of the compiler to be notified about all recently
+introduced warnings.
Restrict the Amount of Ether
============================
@@ -305,6 +322,12 @@ of "failsafe" mode, which, for example, disables most of the features, hands ove
control to a fixed and trusted third party or just converts the contract into
a simple "give me back my money" contract.
+Ask for Peer Review
+===================
+
+The more people examine a piece of code, the more issues are found.
+Asking people to review your code also helps as a cross-check to find out whether your code
+is easy to understand - a very important criterion for good smart contracts.
*******************
Formal Verification
diff --git a/docs/yul.rst b/docs/yul.rst
index e010a708..cfeec4db 100644
--- a/docs/yul.rst
+++ b/docs/yul.rst
@@ -83,6 +83,7 @@ Grammar::
FunctionDefinition |
VariableDeclaration |
Assignment |
+ If |
Expression |
Switch |
ForLoop |
@@ -417,6 +418,12 @@ The following functions must be available:
| create(v:u256, p:u256, s:u256) | create new contract with code mem[p..(p+s)) and send v wei |
| | and return the new address |
+---------------------------------------------+-----------------------------------------------------------------+
+| create2(v:u256, n:u256, p:u256, s:u256) | create new contract with code mem[p...(p+s)) at address |
+| | keccak256(0xff . self . n . keccak256(mem[p...(p+s))) |
+| | and send v wei and return the new address, where ``0xff`` is a |
+| | 8 byte value, ``self`` is the current contract's address |
+| | as a 20 byte value and ``n`` is a big-endian 256-bit value |
++---------------------------------------------+-----------------------------------------------------------------+
| call(g:u256, a:u256, v:u256, in:u256, | call contract at address a with input mem[in..(in+insize)) |
| insize:u256, out:u256, | providing g gas and v wei and output area |
| outsize:u256) | mem[out..(out+outsize)) returning 0 on error (eg. out of gas) |
@@ -492,6 +499,8 @@ The following functions must be available:
+---------------------------------------------+-----------------------------------------------------------------+
| extcodecopy(a:u256, t:u256, f:u256, s:u256) | like codecopy(t, f, s) but take code at address a |
+---------------------------------------------+-----------------------------------------------------------------+
+| extcodehash(a:u256) | code hash of address a |
++---------------------------------------------+-----------------------------------------------------------------+
| *Others* |
+---------------------------------------------+-----------------------------------------------------------------+
| discard(unused:bool) | discard value |
diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp
index b40617c1..d98b3efa 100644
--- a/libevmasm/GasMeter.cpp
+++ b/libevmasm/GasMeter.cpp
@@ -114,6 +114,9 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _
case Instruction::EXTCODESIZE:
gas = GasCosts::extCodeGas(m_evmVersion);
break;
+ case Instruction::EXTCODEHASH:
+ gas = GasCosts::balanceGas(m_evmVersion);
+ break;
case Instruction::EXTCODECOPY:
gas = GasCosts::extCodeGas(m_evmVersion);
gas += memoryGas(-1, -3);
diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp
index d5b82e75..cf98c938 100644
--- a/libevmasm/Instruction.cpp
+++ b/libevmasm/Instruction.cpp
@@ -73,6 +73,7 @@ const std::map<std::string, Instruction> dev::solidity::c_instructions =
{ "EXTCODECOPY", Instruction::EXTCODECOPY },
{ "RETURNDATASIZE", Instruction::RETURNDATASIZE },
{ "RETURNDATACOPY", Instruction::RETURNDATACOPY },
+ { "EXTCODEHASH", Instruction::EXTCODEHASH },
{ "BLOCKHASH", Instruction::BLOCKHASH },
{ "COINBASE", Instruction::COINBASE },
{ "TIMESTAMP", Instruction::TIMESTAMP },
@@ -216,6 +217,7 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::EXTCODECOPY, { "EXTCODECOPY", 0, 4, 0, true, Tier::ExtCode } },
{ Instruction::RETURNDATASIZE, {"RETURNDATASIZE", 0, 0, 1, false, Tier::Base } },
{ Instruction::RETURNDATACOPY, {"RETURNDATACOPY", 0, 3, 0, true, Tier::VeryLow } },
+ { Instruction::EXTCODEHASH, { "EXTCODEHASH", 0, 1, 1, false, Tier::Balance } },
{ Instruction::BLOCKHASH, { "BLOCKHASH", 0, 1, 1, false, Tier::Ext } },
{ Instruction::COINBASE, { "COINBASE", 0, 0, 1, false, Tier::Base } },
{ Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1, false, Tier::Base } },
diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h
index 50c1f47d..63424eeb 100644
--- a/libevmasm/Instruction.h
+++ b/libevmasm/Instruction.h
@@ -82,6 +82,7 @@ enum class Instruction: uint8_t
EXTCODECOPY, ///< copy external code (from another contract)
RETURNDATASIZE = 0x3d, ///< get size of return data buffer
RETURNDATACOPY = 0x3e, ///< copy return data in current environment to memory
+ EXTCODEHASH = 0x3f, ///< get external code hash (from another contract)
BLOCKHASH = 0x40, ///< get hash of most recent complete block
COINBASE, ///< get the block's coinbase address
diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp
index 71267ee8..78f3c9c7 100644
--- a/libevmasm/SemanticInformation.cpp
+++ b/libevmasm/SemanticInformation.cpp
@@ -151,6 +151,7 @@ bool SemanticInformation::isDeterministic(AssemblyItem const& _item)
case Instruction::MSIZE: // depends on previous writes and reads, not only on content
case Instruction::BALANCE: // depends on previous calls
case Instruction::EXTCODESIZE:
+ case Instruction::EXTCODEHASH:
case Instruction::RETURNDATACOPY: // depends on previous calls
case Instruction::RETURNDATASIZE:
return false;
@@ -172,6 +173,7 @@ bool SemanticInformation::movable(Instruction _instruction)
case Instruction::KECCAK256:
case Instruction::BALANCE:
case Instruction::EXTCODESIZE:
+ case Instruction::EXTCODEHASH:
case Instruction::RETURNDATASIZE:
case Instruction::SLOAD:
case Instruction::PC:
@@ -233,6 +235,7 @@ bool SemanticInformation::invalidInPureFunctions(Instruction _instruction)
case Instruction::GASPRICE:
case Instruction::EXTCODESIZE:
case Instruction::EXTCODECOPY:
+ case Instruction::EXTCODEHASH:
case Instruction::BLOCKHASH:
case Instruction::COINBASE:
case Instruction::TIMESTAMP:
diff --git a/libjulia/optimiser/FullInliner.cpp b/libjulia/optimiser/FullInliner.cpp
index e8776e23..f41dc198 100644
--- a/libjulia/optimiser/FullInliner.cpp
+++ b/libjulia/optimiser/FullInliner.cpp
@@ -89,6 +89,9 @@ void InlineModifier::operator()(ForLoop& _loop)
void InlineModifier::operator()(Block& _block)
{
+ vector<Statement> saved;
+ saved.swap(m_statementsToPrefix);
+
// This is only used if needed to minimize the number of move operations.
vector<Statement> modifiedStatements;
for (size_t i = 0; i < _block.statements.size(); ++i)
@@ -110,6 +113,8 @@ void InlineModifier::operator()(Block& _block)
}
if (!modifiedStatements.empty())
_block.statements = std::move(modifiedStatements);
+
+ saved.swap(m_statementsToPrefix);
}
void InlineModifier::visit(Expression& _expression)
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp
index 8e7a81a6..a11b1146 100644
--- a/libsolidity/ast/AST.cpp
+++ b/libsolidity/ast/AST.cpp
@@ -311,8 +311,6 @@ FunctionTypePointer FunctionDefinition::functionType(bool _internal) const
return make_shared<FunctionType>(*this, _internal);
case Declaration::Visibility::External:
return {};
- default:
- solAssert(false, "visibility() should return a Visibility");
}
}
else
@@ -327,8 +325,6 @@ FunctionTypePointer FunctionDefinition::functionType(bool _internal) const
case Declaration::Visibility::Public:
case Declaration::Visibility::External:
return make_shared<FunctionType>(*this, _internal);
- default:
- solAssert(false, "visibility() should return a Visibility");
}
}
@@ -568,8 +564,6 @@ FunctionTypePointer VariableDeclaration::functionType(bool _internal) const
case Declaration::Visibility::Public:
case Declaration::Visibility::External:
return make_shared<FunctionType>(*this);
- default:
- solAssert(false, "visibility() should not return a Visibility");
}
// To make the compiler happy
diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp
index 8d52851a..cadc5f28 100644
--- a/libsolidity/ast/ASTJsonConverter.cpp
+++ b/libsolidity/ast/ASTJsonConverter.cpp
@@ -752,9 +752,9 @@ string ASTJsonConverter::location(VariableDeclaration::Location _location)
return "memory";
case VariableDeclaration::Location::CallData:
return "calldata";
- default:
- solAssert(false, "Unknown declaration location.");
}
+ // To make the compiler happy
+ return {};
}
string ASTJsonConverter::contractKind(ContractDefinition::ContractKind _kind)
@@ -767,9 +767,10 @@ string ASTJsonConverter::contractKind(ContractDefinition::ContractKind _kind)
return "contract";
case ContractDefinition::ContractKind::Library:
return "library";
- default:
- solAssert(false, "Unknown kind of contract.");
}
+
+ // To make the compiler happy
+ return {};
}
string ASTJsonConverter::functionCallKind(FunctionCallKind _kind)
diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp
index 2b77db8f..d33f749c 100644
--- a/libsolidity/codegen/ArrayUtils.cpp
+++ b/libsolidity/codegen/ArrayUtils.cpp
@@ -1108,8 +1108,6 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck) c
m_context << endTag;
break;
}
- default:
- solAssert(false, "");
}
}
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index e6ad6d9c..2bdf88e3 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -895,15 +895,6 @@ void CompilerUtils::convertType(
typeOnStack.location() == DataLocation::CallData,
"Invalid conversion to calldata type.");
break;
- default:
- solAssert(
- false,
- "Invalid type conversion " +
- _typeOnStack.toString(false) +
- " to " +
- _targetType.toString(false) +
- " requested."
- );
}
break;
}
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index 587cf34a..27440289 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -1098,8 +1098,6 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
case FunctionType::Kind::GasLeft:
m_context << Instruction::GAS;
break;
- default:
- solAssert(false, "Invalid function type.");
}
}
return false;
diff --git a/libsolidity/formal/SMTChecker.cpp b/libsolidity/formal/SMTChecker.cpp
index 49c90405..19785817 100644
--- a/libsolidity/formal/SMTChecker.cpp
+++ b/libsolidity/formal/SMTChecker.cpp
@@ -639,8 +639,6 @@ void SMTChecker::checkCondition(
case smt::CheckResult::ERROR:
m_errorReporter.warning(_location, "Error trying to invoke SMT solver.");
break;
- default:
- solAssert(false, "");
}
m_interface->pop();
}
diff --git a/libsolidity/formal/Z3Interface.cpp b/libsolidity/formal/Z3Interface.cpp
index 747c9172..9a0ccf48 100644
--- a/libsolidity/formal/Z3Interface.cpp
+++ b/libsolidity/formal/Z3Interface.cpp
@@ -91,8 +91,6 @@ pair<CheckResult, vector<string>> Z3Interface::check(vector<Expression> const& _
case z3::check_result::unknown:
result = CheckResult::UNKNOWN;
break;
- default:
- solAssert(false, "");
}
if (result == CheckResult::SATISFIABLE && !_expressionsToEvaluate.empty())
diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp
index 0f2c0f56..947b6d05 100644
--- a/libsolidity/inlineasm/AsmAnalysis.cpp
+++ b/libsolidity/inlineasm/AsmAnalysis.cpp
@@ -568,7 +568,17 @@ void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocatio
// Similarly we assume bitwise shifting and create2 go together.
solAssert(m_evmVersion.hasBitwiseShifting() == m_evmVersion.hasCreate2(), "");
- if ((
+ if (_instr == solidity::Instruction::EXTCODEHASH)
+ m_errorReporter.warning(
+ _location,
+ "The \"" +
+ boost::to_lower_copy(instructionInfo(_instr).name)
+ + "\" instruction is not supported by the VM version \"" +
+ "" + m_evmVersion.name() +
+ "\" you are currently compiling for. " +
+ "It will be interpreted as an invalid instruction on this VM."
+ );
+ else if ((
_instr == solidity::Instruction::RETURNDATACOPY ||
_instr == solidity::Instruction::RETURNDATASIZE ||
_instr == solidity::Instruction::STATICCALL
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp
index adf59a9c..d1001c80 100644
--- a/libsolidity/interface/CompilerStack.cpp
+++ b/libsolidity/interface/CompilerStack.cpp
@@ -988,8 +988,7 @@ Json::Value CompilerStack::gasEstimates(string const& _contractName) const
if (eth::AssemblyItems const* items = assemblyItems(_contractName))
{
Gas executionGas = gasEstimator.functionalEstimation(*items);
- u256 bytecodeSize(runtimeObject(_contractName).bytecode.size());
- Gas codeDepositGas = bytecodeSize * eth::GasCosts::createDataGas;
+ Gas codeDepositGas{eth::GasMeter::dataGas(runtimeObject(_contractName).bytecode, false)};
Json::Value creation(Json::objectValue);
creation["codeDepositCost"] = gasToJson(codeDepositGas);
diff --git a/libsolidity/interface/Exceptions.cpp b/libsolidity/interface/Exceptions.cpp
index a837dce6..ecadd0b7 100644
--- a/libsolidity/interface/Exceptions.cpp
+++ b/libsolidity/interface/Exceptions.cpp
@@ -49,9 +49,6 @@ Error::Error(Type _type, SourceLocation const& _location, string const& _descrip
case Type::Warning:
m_typeName = "Warning";
break;
- default:
- solAssert(false, "");
- break;
}
if (!_location.isEmpty())
diff --git a/scripts/tests.sh b/scripts/tests.sh
index 1c0fc590..c284c05c 100755
--- a/scripts/tests.sh
+++ b/scripts/tests.sh
@@ -100,8 +100,14 @@ else
log_directory=""
fi
-function printError() { echo "$(tput setaf 1)$1$(tput sgr0)"; }
-function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput sgr0)"; }
+if [ "$CIRCLECI" ]
+then
+ function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput setaf 7)"; }
+ function printError() { echo "$(tput setaf 1)$1$(tput setaf 7)"; }
+else
+ function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput sgr0)"; }
+ function printError() { echo "$(tput setaf 1)$1$(tput sgr0)"; }
+fi
printTask "Running commandline tests..."
# Only run in parallel if this is run on CI infrastructure
diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh
index 78e45429..d7b95e8a 100755
--- a/test/cmdlineTests.sh
+++ b/test/cmdlineTests.sh
@@ -37,9 +37,15 @@ FULLARGS="--optimize --ignore-missing --combined-json abi,asm,ast,bin,bin-runtim
echo "Checking that the bug list is up to date..."
"$REPO_ROOT"/scripts/update_bugs_by_version.py
-function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput sgr0)"; }
+if [ "$CIRCLECI" ]
+then
+ function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput setaf 7)"; }
+ function printError() { echo "$(tput setaf 1)$1$(tput setaf 7)"; }
+else
+ function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput sgr0)"; }
+ function printError() { echo "$(tput setaf 1)$1$(tput sgr0)"; }
+fi
-function printError() { echo "$(tput setaf 1)$1$(tput sgr0)"; }
function compileFull()
{
diff --git a/test/libjulia/Inliner.cpp b/test/libjulia/Inliner.cpp
index 43a7d757..d0ecd42f 100644
--- a/test/libjulia/Inliner.cpp
+++ b/test/libjulia/Inliner.cpp
@@ -342,5 +342,40 @@ BOOST_AUTO_TEST_CASE(pop_result)
);
}
+BOOST_AUTO_TEST_CASE(inside_condition)
+{
+ // This tests that breaking the expression inside the condition works properly.
+ BOOST_CHECK_EQUAL(
+ fullInline("{"
+ "if gt(f(mload(1)), mload(0)) {"
+ "sstore(0, 2)"
+ "}"
+ "function f(a) -> r {"
+ "a := mload(a)"
+ "r := add(a, calldatasize())"
+ "}"
+ "}", false),
+ format("{"
+ "{"
+ "let _1 := mload(0)"
+ "let f_a := mload(1)"
+ "let f_r"
+ "{"
+ "f_a := mload(f_a)"
+ "f_r := add(f_a, calldatasize())"
+ "}"
+ "if gt(f_r, _1)"
+ "{"
+ "sstore(0, 2)"
+ "}"
+ "}"
+ "function f(a) -> r"
+ "{"
+ "a := mload(a)"
+ "r := add(a, calldatasize())"
+ "}"
+ "}", false)
+ );
+}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/liblll/Compiler.cpp b/test/liblll/Compiler.cpp
index be798dc8..a4394f54 100644
--- a/test/liblll/Compiler.cpp
+++ b/test/liblll/Compiler.cpp
@@ -186,6 +186,7 @@ BOOST_AUTO_TEST_CASE(valid_opcodes_functional)
"60006000600060003c",
"3d",
"6000600060003e",
+ "60003f",
"600040",
"41",
"42",
@@ -291,6 +292,7 @@ BOOST_AUTO_TEST_CASE(valid_opcodes_functional)
"{ (EXTCODECOPY 0 0 0 0) }",
"{ (RETURNDATASIZE) }",
"{ (RETURNDATACOPY 0 0 0) }",
+ "{ (EXTCODEHASH 0) }",
"{ (BLOCKHASH 0) }",
"{ (COINBASE) }",
"{ (TIMESTAMP) }",
@@ -409,6 +411,7 @@ BOOST_AUTO_TEST_CASE(valid_opcodes_asm)
"3c",
"3d",
"3e",
+ "3f",
"40",
"41",
"42",
@@ -547,6 +550,7 @@ BOOST_AUTO_TEST_CASE(valid_opcodes_asm)
"{ (asm EXTCODECOPY) }",
"{ (asm RETURNDATASIZE) }",
"{ (asm RETURNDATACOPY) }",
+ "{ (asm EXTCODEHASH) }",
"{ (asm BLOCKHASH) }",
"{ (asm COINBASE) }",
"{ (asm TIMESTAMP) }",
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index b2e2b63b..640bf4d0 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -415,6 +415,19 @@ BOOST_AUTO_TEST_CASE(create2_as_variable)
CHECK_ALLOW_MULTI(text, expectations);
}
+BOOST_AUTO_TEST_CASE(extcodehash_as_variable)
+{
+ char const* text = R"(
+ contract c { function f() public view { uint extcodehash; extcodehash; assembly { pop(extcodehash(0)) } }}
+ )";
+ // This needs special treatment, because the message mentions the EVM version,
+ // so cannot be run via isoltest.
+ CHECK_ALLOW_MULTI(text, (std::vector<std::pair<Error::Type, std::string>>{
+ {Error::Type::Warning, "Variable is shadowed in inline assembly by an instruction of the same name"},
+ {Error::Type::Warning, "The \"extcodehash\" instruction is not supported by the VM version"},
+ }));
+}
+
BOOST_AUTO_TEST_CASE(getter_is_memory_type)
{
char const* text = R"(
diff --git a/test/tools/fuzzer.cpp b/test/tools/fuzzer.cpp
index a5a63854..ce4b721f 100644
--- a/test/tools/fuzzer.cpp
+++ b/test/tools/fuzzer.cpp
@@ -84,12 +84,8 @@ void testConstantOptimizer()
}
}
-void testStandardCompiler()
+void runCompiler(string input)
{
- if (!quiet)
- cout << "Testing compiler via JSON interface." << endl;
- string input = readStandardInput();
-
string outputString(compileStandard(input.c_str(), NULL));
Json::Value output;
if (!jsonParseStrict(outputString, output))
@@ -112,52 +108,37 @@ void testStandardCompiler()
}
}
+void testStandardCompiler()
+{
+ if (!quiet)
+ cout << "Testing compiler via JSON interface." << endl;
+ string input = readStandardInput();
+
+ runCompiler(input);
+}
+
void testCompiler(bool optimize)
{
if (!quiet)
cout << "Testing compiler " << (optimize ? "with" : "without") << " optimizer." << endl;
string input = readStandardInput();
- string outputString(compileJSON(input.c_str(), optimize));
- Json::Value outputJson;
- if (!jsonParseStrict(outputString, outputJson))
- {
- cout << "Compiler produced invalid JSON output." << endl;
- abort();
- }
- if (outputJson.isMember("errors"))
- {
- if (!outputJson["errors"].isArray())
- {
- cout << "Output JSON has \"errors\" but it is not an array." << endl;
- abort();
- }
- for (Json::Value const& error: outputJson["errors"])
- {
- string invalid = contains(error.asString(), vector<string>{
- // StandardJSON error types
- "Exception",
- "InternalCompilerError",
- // Old-school error messages
- "Internal compiler error",
- "Exception during compilation",
- "Unknown exception during compilation",
- "Unknown exception while generating contract data output",
- "Unknown exception while generating source name output",
- "Unknown error while generating JSON"
- });
- if (!invalid.empty())
- {
- cout << "Invalid error: \"" << error.asString() << "\"" << endl;
- abort();
- }
- }
- }
- else if (!outputJson.isMember("contracts"))
- {
- cout << "Output JSON has neither \"errors\" nor \"contracts\"." << endl;
- abort();
- }
+ Json::Value config = Json::objectValue;
+ config["language"] = "Solidity";
+ config["sources"] = Json::objectValue;
+ config["sources"][""] = Json::objectValue;
+ config["sources"][""]["content"] = input;
+ config["settings"] = Json::objectValue;
+ config["settings"]["optimizer"] = Json::objectValue;
+ config["settings"]["optimizer"]["enabled"] = optimize;
+ config["settings"]["optimizer"]["runs"] = 200;
+
+ // Enable all SourceUnit-level outputs.
+ config["settings"]["outputSelection"]["*"][""][0] = "*";
+ // Enable all Contract-level outputs.
+ config["settings"]["outputSelection"]["*"]["*"][0] = "*";
+
+ runCompiler(jsonCompactPrint(config));
}
}