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

This commit is contained in:
chriseth 2020-09-29 09:53:50 +02:00
commit 4bdec8107c
509 changed files with 1813 additions and 932 deletions

View File

@ -4,39 +4,48 @@ Breaking Changes:
* Type System: Unary negation can only be used on signed integers, not on unsigned integers. * Type System: Unary negation can only be used on signed integers, not on unsigned integers.
### 0.7.2 (unreleased) ### 0.7.3 (unreleased)
Language Features:
### 0.7.2 (2020-09-28)
Important Bugfixes:
* Type Checker: Disallow two or more free functions with identical name (potentially imported and aliased) and parameter types.
Compiler Features: Compiler Features:
* Export compiler-generated utility sources via standard-json or combined-json. * Export compiler-generated utility sources via standard-json or combined-json.
* SMTChecker: Support events and low-level logs.
* SMTChecker: Support ``revert()``.
* SMTChecker: Support shifts.
* SMTChecker: Support compound and, or, and xor operators.
* SMTChecker: Support structs.
* SMTChecker: Support ``type(T).min``, ``type(T).max``, and ``type(I).interfaceId``.
* SMTChecker: Support ``address`` type conversion with literals, e.g. ``address(0)``.
* Type Checker: Report position of first invalid UTF-8 sequence in ``unicode""`` literals.
* Type Checker: More detailed error messages why implicit conversions fail.
* Type Checker: Explain why oversized hex string literals can not be explicitly converted to a shorter ``bytesNN`` type.
* Yul Optimizer: Prune unused parameters in functions.
* Yul Optimizer: Inline into functions further down in the call graph first.
* Yul Optimizer: Try to simplify function names.
* Yul IR Generator: Report source locations related to unimplemented features.
* Optimizer: Optimize ``exp`` when base is 0, 1 or 2. * Optimizer: Optimize ``exp`` when base is 0, 1 or 2.
* SMTChecker: Keep knowledge about string literals, even through assignment, and thus support the ``.length`` property properly.
* SMTChecker: Support ``address`` type conversion with literals, e.g. ``address(0)``.
* SMTChecker: Support ``revert()``.
* SMTChecker: Support ``type(T).min``, ``type(T).max``, and ``type(I).interfaceId``.
* SMTChecker: Support compound and, or, and xor operators.
* SMTChecker: Support events and low-level logs.
* SMTChecker: Support fixed bytes index access.
* SMTChecker: Support memory allocation, e.g. ``new bytes(123)``.
* SMTChecker: Support shifts.
* SMTChecker: Support structs.
* Type Checker: Explain why oversized hex string literals can not be explicitly converted to a shorter ``bytesNN`` type.
* Type Checker: More detailed error messages why implicit conversions fail.
* Type Checker: Report position of first invalid UTF-8 sequence in ``unicode""`` literals.
* Yul IR Generator: Report source locations related to unimplemented features.
* Yul Optimizer: Inline into functions further down in the call graph first.
* Yul Optimizer: Prune unused parameters in functions.
* Yul Optimizer: Try to simplify function names.
Bugfixes: Bugfixes:
* Code generator: Fix internal error on stripping dynamic types from return parameters on EVM versions without ``RETURNDATACOPY``. * Code generator: Fix internal error on stripping dynamic types from return parameters on EVM versions without ``RETURNDATACOPY``.
* Type Checker: Add missing check against nested dynamic arrays in ABI encoding functions when ABIEncoderV2 is disabled. * Type Checker: Add missing check against nested dynamic arrays in ABI encoding functions when ABIEncoderV2 is disabled.
* Type Checker: Disallow ``virtual`` for modifiers in libraries.
* Type Checker: Correct the error message for invalid named parameter in a call to refer to the right argument. * Type Checker: Correct the error message for invalid named parameter in a call to refer to the right argument.
* Type Checker: Correct the warning for homonymous, but not shadowing declarations. * Type Checker: Correct the warning for homonymous, but not shadowing declarations.
* ViewPureChecker: Prevent visibility check on constructors. * Type Checker: Disallow ``virtual`` for modifiers in libraries.
* Type system: Fix internal error on implicit conversion of contract instance to the type of its ``super``. * Type system: Fix internal error on implicit conversion of contract instance to the type of its ``super``.
* Type system: Fix internal error on implicit conversion of string literal to a calldata string. * Type system: Fix internal error on implicit conversion of string literal to a calldata string.
* Type system: Fix named parameters in overloaded function and event calls being matched incorrectly if the order differs from the declaration. * Type system: Fix named parameters in overloaded function and event calls being matched incorrectly if the order differs from the declaration.
* ViewPureChecker: Prevent visibility check on constructors.
### 0.7.1 (2020-09-02) ### 0.7.1 (2020-09-02)

View File

@ -537,7 +537,7 @@ For example,
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.6.99 <0.9.0;
contract Test { contract Test {

View File

@ -140,7 +140,7 @@ Local Solidity variables are available for assignments, for example:
.. code:: .. code::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract C { contract C {
uint b; uint b;

View File

@ -1,4 +1,12 @@
[ [
{
"name": "FreeFunctionRedefinition",
"summary": "The compiler does not flag an error when two or more free functions with the same name and parameter types are defined in a source unit or when an imported free function alias shadows another free function with a different name but identical parameter types.",
"description": "In contrast to functions defined inside contracts, free functions with identical names and parameter types did not create an error. Both definition of free functions with identical name and parameter types and an imported free function with an alias that shadows another function with a different name but identical parameter types were permitted due to which a call to either the multiply defined free function or the imported free function alias within a contract led to the execution of that free function which was defined first within the source unit. Subsequently defined identical free function definitions were silently ignored and their code generation was skipped.",
"introduced": "0.7.1",
"fixed": "0.7.2",
"severity": "low"
},
{ {
"name": "UsingForCalldata", "name": "UsingForCalldata",
"summary": "Function calls to internal library functions with calldata parameters called via ``using for`` can result in invalid data being read.", "summary": "Function calls to internal library functions with calldata parameters called via ``using for`` can result in invalid data being read.",

View File

@ -1187,7 +1187,13 @@
"released": "2020-07-28" "released": "2020-07-28"
}, },
"0.7.1": { "0.7.1": {
"bugs": [], "bugs": [
"FreeFunctionRedefinition"
],
"released": "2020-09-02" "released": "2020-09-02"
},
"0.7.2": {
"bugs": [],
"released": "2020-09-28"
} }
} }

View File

@ -28,7 +28,7 @@ you receive the funds of the person who is now the richest.
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract WithdrawalContract { contract WithdrawalContract {
address public richest; address public richest;
@ -62,7 +62,7 @@ This is as opposed to the more intuitive sending pattern:
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract SendContract { contract SendContract {
address payable public richest; address payable public richest;

View File

@ -26,7 +26,7 @@ Not all types for constants and immutables are implemented at this time. The onl
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract C { contract C {
uint constant X = 32**22 + 8; uint constant X = 32**22 + 8;

View File

@ -39,7 +39,7 @@ Details are given in the following example.
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract Owned { contract Owned {
@ -127,7 +127,7 @@ destruction request. The way this is done is problematic, as
seen in the following example:: seen in the following example::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract owned { contract owned {
constructor() { owner = msg.sender; } constructor() { owner = msg.sender; }
@ -157,7 +157,7 @@ explicitly in the final override, but this function will bypass
``Base1.destroy``. The way around this is to use ``super``:: ``Base1.destroy``. The way around this is to use ``super``::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract owned { contract owned {
constructor() { owner = msg.sender; } constructor() { owner = msg.sender; }
@ -214,7 +214,7 @@ The following example demonstrates changing mutability and visibility:
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract Base contract Base
{ {
@ -405,7 +405,7 @@ equivalent to ``constructor() {}``. For example:
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
abstract contract A { abstract contract A {
uint public a; uint public a;
@ -442,7 +442,7 @@ linearization rules explained below. If the base constructors have arguments,
derived contracts need to specify all of them. This can be done in two ways:: derived contracts need to specify all of them. This can be done in two ways::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract Base { contract Base {
uint x; uint x;
@ -523,7 +523,7 @@ One area where inheritance linearization is especially important and perhaps not
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract Base1 { contract Base1 {
constructor() {} constructor() {}

View File

@ -192,8 +192,7 @@ is compiled so recursive creation-dependencies are not possible.
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract D { contract D {
uint public x; uint public x;
constructor(uint a) payable { constructor(uint a) payable {
@ -248,8 +247,7 @@ which only need to be created if there is a dispute.
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract D { contract D {
uint public x; uint public x;
constructor(uint a) { constructor(uint a) {

View File

@ -25,8 +25,7 @@ to receive their money - contracts cannot activate themselves.
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract SimpleAuction { contract SimpleAuction {
// Parameters of the auction. Times are either // Parameters of the auction. Times are either
// absolute unix timestamps (seconds since 1970-01-01) // absolute unix timestamps (seconds since 1970-01-01)
@ -186,8 +185,7 @@ invalid bids.
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract BlindAuction { contract BlindAuction {
struct Bid { struct Bid {
bytes32 blindedBid; bytes32 blindedBid;

View File

@ -142,8 +142,7 @@ The full contract
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract ReceiverPays { contract ReceiverPays {
address owner = msg.sender; address owner = msg.sender;
@ -339,8 +338,7 @@ The full contract
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract SimplePaymentChannel { contract SimplePaymentChannel {
address payable public sender; // The account sending payments. address payable public sender; // The account sending payments.
address payable public recipient; // The account receiving the payments. address payable public recipient; // The account receiving the payments.

View File

@ -26,8 +26,7 @@ you can use state machine-like constructs inside a contract.
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract Purchase { contract Purchase {
uint public value; uint public value;
address payable public seller; address payable public seller;

View File

@ -33,8 +33,7 @@ of votes.
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
/// @title Voting with delegation. /// @title Voting with delegation.
contract Ballot { contract Ballot {
// This declares a new complex type which will // This declares a new complex type which will

View File

@ -201,8 +201,7 @@ Never use tx.origin for authorization. Let's say you have a wallet contract like
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
// THIS CONTRACT CONTAINS A BUG - DO NOT USE // THIS CONTRACT CONTAINS A BUG - DO NOT USE
contract TxUserWallet { contract TxUserWallet {
address owner; address owner;
@ -222,8 +221,7 @@ Now someone tricks you into sending Ether to the address of this attack wallet:
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
interface TxUserWallet { interface TxUserWallet {
function transferTo(address payable dest, uint amount) external; function transferTo(address payable dest, uint amount) external;
} }

View File

@ -300,8 +300,7 @@ Within a grouping, place the ``view`` and ``pure`` functions last.
Yes:: Yes::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract A { contract A {
constructor() { constructor() {
// ... // ...
@ -337,8 +336,7 @@ Yes::
No:: No::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract A { contract A {
// External functions // External functions
@ -758,8 +756,7 @@ manner as modifiers if the function declaration is long or hard to read.
Yes:: Yes::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
// Base contracts just to make this compile // Base contracts just to make this compile
contract B { contract B {
constructor(uint) { constructor(uint) {
@ -790,8 +787,7 @@ Yes::
No:: No::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
// Base contracts just to make this compile // Base contracts just to make this compile
contract B { contract B {
@ -1012,8 +1008,7 @@ As shown in the example below, if the contract name is ``Congress`` and the libr
Yes:: Yes::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
// Owned.sol // Owned.sol
contract Owned { contract Owned {
@ -1048,8 +1043,7 @@ and in ``Congress.sol``::
No:: No::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
// owned.sol // owned.sol
contract owned { contract owned {

View File

@ -434,8 +434,7 @@ Array slices are useful to ABI-decode secondary data passed in function paramete
:: ::
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >0.6.99 <0.9.0; pragma solidity >=0.7.0 <0.9.0;
contract Proxy { contract Proxy {
/// @dev Address of the client contract managed by proxy i.e., this contract /// @dev Address of the client contract managed by proxy i.e., this contract
address client; address client;

View File

@ -314,6 +314,7 @@ Input Description
// evm.bytecode.opcodes - Opcodes list // evm.bytecode.opcodes - Opcodes list
// evm.bytecode.sourceMap - Source mapping (useful for debugging) // evm.bytecode.sourceMap - Source mapping (useful for debugging)
// evm.bytecode.linkReferences - Link references (if unlinked object) // evm.bytecode.linkReferences - Link references (if unlinked object)
// evm.bytecode.generatedSources - Sources generated by the compiler
// evm.deployedBytecode* - Deployed bytecode (has all the options that evm.bytecode has) // evm.deployedBytecode* - Deployed bytecode (has all the options that evm.bytecode has)
// evm.deployedBytecode.immutableReferences - Map from AST ids to bytecode ranges that reference immutables // evm.deployedBytecode.immutableReferences - Map from AST ids to bytecode ranges that reference immutables
// evm.methodIdentifiers - The list of function hashes // evm.methodIdentifiers - The list of function hashes
@ -427,6 +428,18 @@ Output Description
"opcodes": "", "opcodes": "",
// The source mapping as a string. See the source mapping definition. // The source mapping as a string. See the source mapping definition.
"sourceMap": "", "sourceMap": "",
// Array of sources generated by the compiler. Currently only
// contains a single Yul file.
"generatedSources": [{
// Yul AST
"ast": { ... }
// Source file in its text form (may contain comments)
"contents":"{ function abi_decode(start, end) -> data { data := calldataload(start) } }",
// Source file ID, used for source references, same "namespace" as the Solidity source files
"id": 2,
"language": "Yul",
"name": "#utility.yul"
}]
// If given, this is an unlinked object. // If given, this is an unlinked object.
"linkReferences": { "linkReferences": {
"libraryFile.sol": { "libraryFile.sol": {
@ -693,8 +706,8 @@ have to be updated manually.)
.. code-block:: Solidity .. code-block:: Solidity
pragma solidity >0.6.99 <0.9.0;
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
abstract contract C { abstract contract C {
// FIXME: remove constructor visibility and make the contract abstract // FIXME: remove constructor visibility and make the contract abstract
constructor() {} constructor() {}

View File

@ -95,9 +95,12 @@ pair<CheckResult, CHCSolverInterface::CexGraph> Z3CHCInterface::query(Expression
} }
// TODO retrieve model / invariants // TODO retrieve model / invariants
} }
catch (z3::exception const&) catch (z3::exception const& _err)
{ {
result = CheckResult::ERROR; if (_err.msg() == string("max. resource limit exceeded"))
result = CheckResult::UNKNOWN;
else
result = CheckResult::ERROR;
cex = {}; cex = {};
} }

View File

@ -38,15 +38,45 @@ namespace
{ {
template <class T, class B> template <class T, class B>
bool hasEqualNameAndParameters(T const& _a, B const& _b) bool hasEqualParameters(T const& _a, B const& _b)
{ {
return return FunctionType(_a).asExternallyCallableFunction(false)->hasEqualParameterTypes(
_a.name() == _b.name() && *FunctionType(_b).asExternallyCallableFunction(false)
FunctionType(_a).asExternallyCallableFunction(false)->hasEqualParameterTypes( );
*FunctionType(_b).asExternallyCallableFunction(false)
);
} }
template<typename T>
map<ASTString, vector<T const*>> filterDeclarations(
map<ASTString, vector<Declaration const*>> const& _declarations)
{
map<ASTString, vector<T const*>> filteredDeclarations;
for (auto const& [name, overloads]: _declarations)
for (auto const* declaration: overloads)
if (auto typedDeclaration = dynamic_cast<T const*>(declaration))
filteredDeclarations[name].push_back(typedDeclaration);
return filteredDeclarations;
}
}
bool ContractLevelChecker::check(SourceUnit const& _sourceUnit)
{
bool noErrors = true;
findDuplicateDefinitions(
filterDeclarations<FunctionDefinition>(*_sourceUnit.annotation().exportedSymbols)
);
// This check flags duplicate free events when free events become
// a Solidity feature
findDuplicateDefinitions(
filterDeclarations<EventDefinition>(*_sourceUnit.annotation().exportedSymbols)
);
if (!Error::containsOnlyWarnings(m_errorReporter.errors()))
noErrors = false;
for (ASTPointer<ASTNode> const& node: _sourceUnit.nodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
if (!check(*contract))
noErrors = false;
return noErrors;
} }
bool ContractLevelChecker::check(ContractDefinition const& _contract) bool ContractLevelChecker::check(ContractDefinition const& _contract)
@ -143,8 +173,21 @@ void ContractLevelChecker::findDuplicateDefinitions(map<string, vector<T>> const
SecondarySourceLocation ssl; SecondarySourceLocation ssl;
for (size_t j = i + 1; j < overloads.size(); ++j) for (size_t j = i + 1; j < overloads.size(); ++j)
if (hasEqualNameAndParameters(*overloads[i], *overloads[j])) if (hasEqualParameters(*overloads[i], *overloads[j]))
{ {
solAssert(
(
dynamic_cast<ContractDefinition const*>(overloads[i]->scope()) &&
dynamic_cast<ContractDefinition const*>(overloads[j]->scope()) &&
overloads[i]->name() == overloads[j]->name()
) ||
(
dynamic_cast<SourceUnit const*>(overloads[i]->scope()) &&
dynamic_cast<SourceUnit const*>(overloads[j]->scope())
),
"Override is neither a namesake function/event in contract scope nor "
"a free function/event (alias)."
);
ssl.append("Other declaration is here:", overloads[j]->location()); ssl.append("Other declaration is here:", overloads[j]->location());
reported.insert(j); reported.insert(j);
} }

View File

@ -39,7 +39,7 @@ namespace solidity::frontend
/** /**
* Component that verifies overloads, abstract contracts, function clashes and others * Component that verifies overloads, abstract contracts, function clashes and others
* checks at contract or function level. * checks at file, contract, or function level.
*/ */
class ContractLevelChecker class ContractLevelChecker
{ {
@ -51,11 +51,14 @@ public:
m_errorReporter(_errorReporter) m_errorReporter(_errorReporter)
{} {}
/// Performs checks on the given source ast.
/// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings
bool check(SourceUnit const& _sourceUnit);
private:
/// Performs checks on the given contract. /// Performs checks on the given contract.
/// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings /// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings
bool check(ContractDefinition const& _contract); bool check(ContractDefinition const& _contract);
private:
/// Checks that two functions defined in this contract with the same name have different /// Checks that two functions defined in this contract with the same name have different
/// arguments and that there is at most one constructor. /// arguments and that there is at most one constructor.
void checkDuplicateFunctions(ContractDefinition const& _contract); void checkDuplicateFunctions(ContractDefinition const& _contract);

View File

@ -109,7 +109,7 @@ bool NameAndTypeResolver::performImports(SourceUnit& _sourceUnit, map<string, So
else else
for (Declaration const* declaration: declarations) for (Declaration const* declaration: declarations)
if (!DeclarationRegistrationHelper::registerDeclaration( if (!DeclarationRegistrationHelper::registerDeclaration(
target, *declaration, alias.alias.get(), &alias.location, true, false, m_errorReporter target, *declaration, alias.alias.get(), &alias.location, false, m_errorReporter
)) ))
error = true; error = true;
} }
@ -117,10 +117,11 @@ bool NameAndTypeResolver::performImports(SourceUnit& _sourceUnit, map<string, So
for (auto const& nameAndDeclaration: scope->second->declarations()) for (auto const& nameAndDeclaration: scope->second->declarations())
for (auto const& declaration: nameAndDeclaration.second) for (auto const& declaration: nameAndDeclaration.second)
if (!DeclarationRegistrationHelper::registerDeclaration( if (!DeclarationRegistrationHelper::registerDeclaration(
target, *declaration, &nameAndDeclaration.first, &imp->location(), true, false, m_errorReporter target, *declaration, &nameAndDeclaration.first, &imp->location(), false, m_errorReporter
)) ))
error = true; error = true;
} }
_sourceUnit.annotation().exportedSymbols = m_scopes[&_sourceUnit]->declarations();
return !error; return !error;
} }
@ -446,7 +447,6 @@ bool DeclarationRegistrationHelper::registerDeclaration(
Declaration const& _declaration, Declaration const& _declaration,
string const* _name, string const* _name,
SourceLocation const* _errorLocation, SourceLocation const* _errorLocation,
bool _warnOnShadow,
bool _inactive, bool _inactive,
ErrorReporter& _errorReporter ErrorReporter& _errorReporter
) )
@ -456,7 +456,11 @@ bool DeclarationRegistrationHelper::registerDeclaration(
string name = _name ? *_name : _declaration.name(); string name = _name ? *_name : _declaration.name();
Declaration const* shadowedDeclaration = nullptr; Declaration const* shadowedDeclaration = nullptr;
if (_warnOnShadow && !name.empty() && _container.enclosingContainer()) // Do not warn about shadowing for structs and enums because their members are
// not accessible without prefixes. Also do not warn about event parameters
// because they do not participate in any proper scope.
bool warnOnShadow = !_declaration.isStructMember() && !_declaration.isEnumValue() && !_declaration.isEventParameter();
if (warnOnShadow && !name.empty() && _container.enclosingContainer())
for (auto const* decl: _container.enclosingContainer()->resolveName(name, true, true)) for (auto const* decl: _container.enclosingContainer()->resolveName(name, true, true))
shadowedDeclaration = decl; shadowedDeclaration = decl;
@ -533,7 +537,6 @@ bool DeclarationRegistrationHelper::visit(SourceUnit& _sourceUnit)
void DeclarationRegistrationHelper::endVisit(SourceUnit& _sourceUnit) void DeclarationRegistrationHelper::endVisit(SourceUnit& _sourceUnit)
{ {
_sourceUnit.annotation().exportedSymbols = m_scopes[&_sourceUnit]->declarations();
ASTVisitor::endVisit(_sourceUnit); ASTVisitor::endVisit(_sourceUnit);
} }
@ -623,23 +626,13 @@ void DeclarationRegistrationHelper::closeCurrentScope()
void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaration) void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaration)
{ {
solAssert(m_currentScope && m_scopes.count(m_currentScope), "No current scope."); solAssert(m_currentScope && m_scopes.count(m_currentScope), "No current scope.");
solAssert(m_currentScope == _declaration.scope(), "Unexpected current scope.");
bool warnAboutShadowing = true;
// Do not warn about shadowing for structs and enums because their members are
// not accessible without prefixes. Also do not warn about event parameters
// because they don't participate in any proper scope.
if (
dynamic_cast<StructDefinition const*>(m_currentScope) ||
dynamic_cast<EnumDefinition const*>(m_currentScope) ||
dynamic_cast<EventDefinition const*>(m_currentScope)
)
warnAboutShadowing = false;
// Register declaration as inactive if we are in block scope. // Register declaration as inactive if we are in block scope.
bool inactive = bool inactive =
(dynamic_cast<Block const*>(m_currentScope) || dynamic_cast<ForStatement const*>(m_currentScope)); (dynamic_cast<Block const*>(m_currentScope) || dynamic_cast<ForStatement const*>(m_currentScope));
registerDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, warnAboutShadowing, inactive, m_errorReporter); registerDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, inactive, m_errorReporter);
solAssert(_declaration.annotation().scope == m_currentScope, ""); solAssert(_declaration.annotation().scope == m_currentScope, "");
solAssert(_declaration.annotation().contract == m_currentContract, ""); solAssert(_declaration.annotation().contract == m_currentContract, "");

View File

@ -152,7 +152,6 @@ public:
Declaration const& _declaration, Declaration const& _declaration,
std::string const* _name, std::string const* _name,
langutil::SourceLocation const* _errorLocation, langutil::SourceLocation const* _errorLocation,
bool _warnOnShadow,
bool _inactive, bool _inactive,
langutil::ErrorReporter& _errorReporter langutil::ErrorReporter& _errorReporter
); );

View File

@ -2922,6 +2922,9 @@ bool TypeChecker::visit(IndexRangeAccess const& _access)
isPure = false; isPure = false;
} }
_access.annotation().isLValue = isLValue;
_access.annotation().isPure = isPure;
TypePointer exprType = type(_access.baseExpression()); TypePointer exprType = type(_access.baseExpression());
if (exprType->category() == Type::Category::TypeType) if (exprType->category() == Type::Category::TypeType)
{ {
@ -2936,14 +2939,11 @@ bool TypeChecker::visit(IndexRangeAccess const& _access)
else if (!(arrayType = dynamic_cast<ArrayType const*>(exprType))) else if (!(arrayType = dynamic_cast<ArrayType const*>(exprType)))
m_errorReporter.fatalTypeError(4781_error, _access.location(), "Index range access is only possible for arrays and array slices."); m_errorReporter.fatalTypeError(4781_error, _access.location(), "Index range access is only possible for arrays and array slices.");
if (arrayType->location() != DataLocation::CallData || !arrayType->isDynamicallySized()) if (arrayType->location() != DataLocation::CallData || !arrayType->isDynamicallySized())
m_errorReporter.typeError(1227_error, _access.location(), "Index range access is only supported for dynamic calldata arrays."); m_errorReporter.typeError(1227_error, _access.location(), "Index range access is only supported for dynamic calldata arrays.");
else if (arrayType->baseType()->isDynamicallyEncoded()) else if (arrayType->baseType()->isDynamicallyEncoded())
m_errorReporter.typeError(2148_error, _access.location(), "Index range access is not supported for arrays with dynamically encoded base types."); m_errorReporter.typeError(2148_error, _access.location(), "Index range access is not supported for arrays with dynamically encoded base types.");
_access.annotation().type = TypeProvider::arraySlice(*arrayType); _access.annotation().type = TypeProvider::arraySlice(*arrayType);
_access.annotation().isLValue = isLValue;
_access.annotation().isPure = isPure;
return false; return false;
} }

View File

@ -495,6 +495,24 @@ string Scopable::sourceUnitName() const
return *sourceUnit().annotation().path; return *sourceUnit().annotation().path;
} }
bool Declaration::isEnumValue() const
{
solAssert(scope(), "");
return dynamic_cast<EnumDefinition const*>(scope());
}
bool Declaration::isStructMember() const
{
solAssert(scope(), "");
return dynamic_cast<StructDefinition const*>(scope());
}
bool Declaration::isEventParameter() const
{
solAssert(scope(), "");
return dynamic_cast<EventDefinition const*>(scope());
}
DeclarationAnnotation& Declaration::annotation() const DeclarationAnnotation& Declaration::annotation() const
{ {
return initAnnotation<DeclarationAnnotation>(); return initAnnotation<DeclarationAnnotation>();
@ -617,11 +635,6 @@ bool VariableDeclaration::isLibraryFunctionParameter() const
return false; return false;
} }
bool VariableDeclaration::isEventParameter() const
{
return dynamic_cast<EventDefinition const*>(scope()) != nullptr;
}
bool VariableDeclaration::hasReferenceOrMappingType() const bool VariableDeclaration::hasReferenceOrMappingType() const
{ {
solAssert(typeName().annotation().type, "Can only be called after reference resolution"); solAssert(typeName().annotation().type, "Can only be called after reference resolution");
@ -629,6 +642,11 @@ bool VariableDeclaration::hasReferenceOrMappingType() const
return type->category() == Type::Category::Mapping || dynamic_cast<ReferenceType const*>(type); return type->category() == Type::Category::Mapping || dynamic_cast<ReferenceType const*>(type);
} }
bool VariableDeclaration::isStateVariable() const
{
return dynamic_cast<ContractDefinition const*>(scope());
}
set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocations() const set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocations() const
{ {
using Location = VariableDeclaration::Location; using Location = VariableDeclaration::Location;

View File

@ -258,10 +258,16 @@ public:
bool isVisibleAsLibraryMember() const { return visibility() >= Visibility::Internal; } bool isVisibleAsLibraryMember() const { return visibility() >= Visibility::Internal; }
virtual bool isVisibleViaContractTypeAccess() const { return false; } virtual bool isVisibleViaContractTypeAccess() const { return false; }
virtual bool isLValue() const { return false; } virtual bool isLValue() const { return false; }
virtual bool isPartOfExternalInterface() const { return false; } virtual bool isPartOfExternalInterface() const { return false; }
/// @returns true if this is a declaration of an enum member.
bool isEnumValue() const;
/// @returns true if this is a declaration of a struct member.
bool isStructMember() const;
/// @returns true if this is a declaration of a parameter of an event.
bool isEventParameter() const;
/// @returns the type of expressions referencing this declaration. /// @returns the type of expressions referencing this declaration.
/// This can only be called once types of variable declarations have already been resolved. /// This can only be called once types of variable declarations have already been resolved.
virtual TypePointer type() const = 0; virtual TypePointer type() const = 0;
@ -899,7 +905,6 @@ public:
ASTPointer<Expression> _value, ASTPointer<Expression> _value,
Visibility _visibility, Visibility _visibility,
ASTPointer<StructuredDocumentation> const _documentation = nullptr, ASTPointer<StructuredDocumentation> const _documentation = nullptr,
bool _isStateVar = false,
bool _isIndexed = false, bool _isIndexed = false,
Mutability _mutability = Mutability::Mutable, Mutability _mutability = Mutability::Mutable,
ASTPointer<OverrideSpecifier> _overrides = nullptr, ASTPointer<OverrideSpecifier> _overrides = nullptr,
@ -909,7 +914,6 @@ public:
StructurallyDocumented(std::move(_documentation)), StructurallyDocumented(std::move(_documentation)),
m_typeName(std::move(_type)), m_typeName(std::move(_type)),
m_value(std::move(_value)), m_value(std::move(_value)),
m_isStateVariable(_isStateVar),
m_isIndexed(_isIndexed), m_isIndexed(_isIndexed),
m_mutability(_mutability), m_mutability(_mutability),
m_overrides(std::move(_overrides)), m_overrides(std::move(_overrides)),
@ -952,15 +956,11 @@ public:
bool isConstructorParameter() const; bool isConstructorParameter() const;
/// @returns true iff this variable is a parameter(or return parameter of a library function /// @returns true iff this variable is a parameter(or return parameter of a library function
bool isLibraryFunctionParameter() const; bool isLibraryFunctionParameter() const;
/// @returns true if the type of the variable does not need to be specified, i.e. it is declared
/// in the body of a function or modifier.
/// @returns true if this variable is a parameter of an event.
bool isEventParameter() const;
/// @returns true if the type of the variable is a reference or mapping type, i.e. /// @returns true if the type of the variable is a reference or mapping type, i.e.
/// array, struct or mapping. These types can take a data location (and often require it). /// array, struct or mapping. These types can take a data location (and often require it).
/// Can only be called after reference resolution. /// Can only be called after reference resolution.
bool hasReferenceOrMappingType() const; bool hasReferenceOrMappingType() const;
bool isStateVariable() const { return m_isStateVariable; } bool isStateVariable() const;
bool isIndexed() const { return m_isIndexed; } bool isIndexed() const { return m_isIndexed; }
Mutability mutability() const { return m_mutability; } Mutability mutability() const { return m_mutability; }
bool isConstant() const { return m_mutability == Mutability::Constant; } bool isConstant() const { return m_mutability == Mutability::Constant; }
@ -989,7 +989,6 @@ private:
/// Initially assigned value, can be missing. For local variables, this is stored inside /// Initially assigned value, can be missing. For local variables, this is stored inside
/// VariableDeclarationStatement and not here. /// VariableDeclarationStatement and not here.
ASTPointer<Expression> m_value; ASTPointer<Expression> m_value;
bool m_isStateVariable = false; ///< Whether or not this is a contract state variable
bool m_isIndexed = false; ///< Whether this is an indexed variable (used by events). bool m_isIndexed = false; ///< Whether this is an indexed variable (used by events).
/// Whether the variable is "constant", "immutable" or non-marked (mutable). /// Whether the variable is "constant", "immutable" or non-marked (mutable).
Mutability m_mutability = Mutability::Mutable; Mutability m_mutability = Mutability::Mutable;

View File

@ -454,7 +454,6 @@ ASTPointer<VariableDeclaration> ASTJsonImporter::createVariableDeclaration(Json:
nullOrCast<Expression>(member(_node, "value")), nullOrCast<Expression>(member(_node, "value")),
visibility(_node), visibility(_node),
_node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")), _node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")),
memberAsBool(_node, "stateVariable"),
_node.isMember("indexed") ? memberAsBool(_node, "indexed") : false, _node.isMember("indexed") ? memberAsBool(_node, "indexed") : false,
mutability, mutability,
_node["overrides"].isNull() ? nullptr : createOverrideSpecifier(member(_node, "overrides")), _node["overrides"].isNull() ? nullptr : createOverrideSpecifier(member(_node, "overrides")),

View File

@ -836,7 +836,7 @@ void BMC::checkCondition(
case smtutil::CheckResult::SATISFIABLE: case smtutil::CheckResult::SATISFIABLE:
{ {
std::ostringstream message; std::ostringstream message;
message << _description << " happens here."; message << "BMC: " << _description << " happens here.";
if (_callStack.size()) if (_callStack.size())
{ {
std::ostringstream modelMessage; std::ostringstream modelMessage;
@ -865,13 +865,13 @@ void BMC::checkCondition(
case smtutil::CheckResult::UNSATISFIABLE: case smtutil::CheckResult::UNSATISFIABLE:
break; break;
case smtutil::CheckResult::UNKNOWN: case smtutil::CheckResult::UNKNOWN:
m_errorReporter.warning(_errorMightHappen, _location, _description + " might happen here.", secondaryLocation); m_errorReporter.warning(_errorMightHappen, _location, "BMC: " + _description + " might happen here.", secondaryLocation);
break; break;
case smtutil::CheckResult::CONFLICTING: case smtutil::CheckResult::CONFLICTING:
m_errorReporter.warning(1584_error, _location, "At least two SMT solvers provided conflicting answers. Results might not be sound."); m_errorReporter.warning(1584_error, _location, "BMC: At least two SMT solvers provided conflicting answers. Results might not be sound.");
break; break;
case smtutil::CheckResult::ERROR: case smtutil::CheckResult::ERROR:
m_errorReporter.warning(1823_error, _location, "Error trying to invoke SMT solver."); m_errorReporter.warning(1823_error, _location, "BMC: Error trying to invoke SMT solver.");
break; break;
} }
@ -919,13 +919,13 @@ void BMC::checkBooleanNotConstant(
if (positiveResult == smtutil::CheckResult::SATISFIABLE) if (positiveResult == smtutil::CheckResult::SATISFIABLE)
{ {
solAssert(negatedResult == smtutil::CheckResult::UNSATISFIABLE, ""); solAssert(negatedResult == smtutil::CheckResult::UNSATISFIABLE, "");
description = "Condition is always true."; description = "BMC: Condition is always true.";
} }
else else
{ {
solAssert(positiveResult == smtutil::CheckResult::UNSATISFIABLE, ""); solAssert(positiveResult == smtutil::CheckResult::UNSATISFIABLE, "");
solAssert(negatedResult == smtutil::CheckResult::SATISFIABLE, ""); solAssert(negatedResult == smtutil::CheckResult::SATISFIABLE, "");
description = "Condition is always false."; description = "BMC: Condition is always false.";
} }
m_errorReporter.warning( m_errorReporter.warning(
6838_error, 6838_error,

View File

@ -1103,10 +1103,10 @@ pair<CheckResult, CHCSolverInterface::CexGraph> CHC::query(smtutil::Expression c
case CheckResult::UNKNOWN: case CheckResult::UNKNOWN:
break; break;
case CheckResult::CONFLICTING: case CheckResult::CONFLICTING:
m_outerErrorReporter.warning(1988_error, _location, "At least two SMT solvers provided conflicting answers. Results might not be sound."); m_outerErrorReporter.warning(1988_error, _location, "CHC: At least two SMT solvers provided conflicting answers. Results might not be sound.");
break; break;
case CheckResult::ERROR: case CheckResult::ERROR:
m_outerErrorReporter.warning(1218_error, _location, "Error trying to invoke SMT solver."); m_outerErrorReporter.warning(1218_error, _location, "CHC: Error trying to invoke SMT solver.");
break; break;
} }
return {result, cex}; return {result, cex};
@ -1264,21 +1264,21 @@ void CHC::checkAndReportTarget(
m_outerErrorReporter.warning( m_outerErrorReporter.warning(
_errorReporterId, _errorReporterId,
_scope->location(), _scope->location(),
_satMsg, "CHC: " + _satMsg,
SecondarySourceLocation().append("\nCounterexample:\n" + *cex, SourceLocation{}) SecondarySourceLocation().append("\nCounterexample:\n" + *cex, SourceLocation{})
); );
else else
m_outerErrorReporter.warning( m_outerErrorReporter.warning(
_errorReporterId, _errorReporterId,
_scope->location(), _scope->location(),
_satMsg "CHC: " + _satMsg
); );
} }
else if (!_unknownMsg.empty()) else if (!_unknownMsg.empty())
m_outerErrorReporter.warning( m_outerErrorReporter.warning(
_errorReporterId, _errorReporterId,
_scope->location(), _scope->location(),
_unknownMsg "CHC: " + _unknownMsg
); );
} }

View File

@ -663,6 +663,9 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall)
case FunctionType::Kind::Event: case FunctionType::Kind::Event:
// These can be safely ignored. // These can be safely ignored.
break; break;
case FunctionType::Kind::ObjectCreation:
visitObjectCreation(_funCall);
return;
default: default:
m_errorReporter.warning( m_errorReporter.warning(
4588_error, 4588_error,
@ -735,6 +738,25 @@ void SMTEncoder::visitGasLeft(FunctionCall const& _funCall)
m_context.addAssertion(symbolicVar->currentValue() <= symbolicVar->valueAtIndex(index - 1)); m_context.addAssertion(symbolicVar->currentValue() <= symbolicVar->valueAtIndex(index - 1));
} }
void SMTEncoder::visitObjectCreation(FunctionCall const& _funCall)
{
auto const& args = _funCall.arguments();
solAssert(args.size() >= 1, "");
auto argType = args.front()->annotation().type->category();
solAssert(argType == Type::Category::Integer || argType == Type::Category::RationalNumber, "");
smtutil::Expression arraySize = expr(*args.front());
setSymbolicUnknownValue(arraySize, TypeProvider::uint256(), m_context);
auto symbArray = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(_funCall));
solAssert(symbArray, "");
smt::setSymbolicZeroValue(*symbArray, m_context);
auto zeroElements = symbArray->elements();
symbArray->increaseIndex();
m_context.addAssertion(symbArray->length() == arraySize);
m_context.addAssertion(symbArray->elements() == zeroElements);
}
void SMTEncoder::endVisit(Identifier const& _identifier) void SMTEncoder::endVisit(Identifier const& _identifier)
{ {
if (auto decl = identifierToVariable(_identifier)) if (auto decl = identifierToVariable(_identifier))
@ -834,7 +856,20 @@ void SMTEncoder::endVisit(Literal const& _literal)
else if (smt::isBool(type)) else if (smt::isBool(type))
defineExpr(_literal, smtutil::Expression(_literal.token() == Token::TrueLiteral ? true : false)); defineExpr(_literal, smtutil::Expression(_literal.token() == Token::TrueLiteral ? true : false));
else if (smt::isStringLiteral(type)) else if (smt::isStringLiteral(type))
{
createExpr(_literal); createExpr(_literal);
// Add constraints for the length and values as it is known.
auto symbArray = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(_literal));
solAssert(symbArray, "");
auto value = _literal.value();
m_context.addAssertion(symbArray->length() == value.length());
for (size_t i = 0; i < value.length(); i++)
m_context.addAssertion(
smtutil::Expression::select(symbArray->elements(), i) == size_t(value[i])
);
}
else else
{ {
m_errorReporter.warning( m_errorReporter.warning(
@ -977,13 +1012,36 @@ void SMTEncoder::endVisit(IndexAccess const& _indexAccess)
if (_indexAccess.annotation().type->category() == Type::Category::TypeType) if (_indexAccess.annotation().type->category() == Type::Category::TypeType)
return; return;
if (_indexAccess.baseExpression().annotation().type->category() == Type::Category::FixedBytes) if (auto const* type = dynamic_cast<FixedBytesType const*>(_indexAccess.baseExpression().annotation().type))
{ {
m_errorReporter.warning( smtutil::Expression base = expr(_indexAccess.baseExpression());
7989_error,
_indexAccess.location(), if (type->numBytes() == 1)
"Assertion checker does not yet support index accessing fixed bytes." defineExpr(_indexAccess, base);
); else
{
auto [bvSize, isSigned] = smt::typeBvSizeAndSignedness(_indexAccess.baseExpression().annotation().type);
solAssert(!isSigned, "");
solAssert(bvSize >= 16, "");
solAssert(bvSize % 8 == 0, "");
smtutil::Expression idx = expr(*_indexAccess.indexExpression());
auto bvBase = smtutil::Expression::int2bv(base, bvSize);
auto bvShl = smtutil::Expression::int2bv(idx * 8, bvSize);
auto bvShr = smtutil::Expression::int2bv(bvSize - 8, bvSize);
auto result = (bvBase << bvShl) >> bvShr;
auto anyValue = expr(_indexAccess);
m_context.expression(_indexAccess)->increaseIndex();
unsigned numBytes = bvSize / 8;
auto withBound = smtutil::Expression::ite(
idx < numBytes,
smtutil::Expression::bv2int(result, false),
anyValue
);
defineExpr(_indexAccess, withBound);
}
return; return;
} }
@ -1654,9 +1712,7 @@ void SMTEncoder::assignment(VariableDeclaration const& _variable, Expression con
// This is a special case where the SMT sorts are different. // This is a special case where the SMT sorts are different.
// For now we are unaware of other cases where this happens, but if they do appear // For now we are unaware of other cases where this happens, but if they do appear
// we should extract this into an `implicitConversion` function. // we should extract this into an `implicitConversion` function.
if (_variable.type()->category() != Type::Category::Array || _value.annotation().type->category() != Type::Category::StringLiteral) assignment(_variable, expr(_value, _variable.type()));
assignment(_variable, expr(_value, _variable.type()));
// TODO else { store each string literal byte into the array }
} }
void SMTEncoder::assignment(VariableDeclaration const& _variable, smtutil::Expression const& _value) void SMTEncoder::assignment(VariableDeclaration const& _variable, smtutil::Expression const& _value)

View File

@ -137,6 +137,7 @@ protected:
void visitAssert(FunctionCall const& _funCall); void visitAssert(FunctionCall const& _funCall);
void visitRequire(FunctionCall const& _funCall); void visitRequire(FunctionCall const& _funCall);
void visitGasLeft(FunctionCall const& _funCall); void visitGasLeft(FunctionCall const& _funCall);
void visitObjectCreation(FunctionCall const& _funCall);
void visitTypeConversion(FunctionCall const& _funCall); void visitTypeConversion(FunctionCall const& _funCall);
void visitFunctionIdentifier(Identifier const& _identifier); void visitFunctionIdentifier(Identifier const& _identifier);

View File

@ -366,12 +366,10 @@ bool CompilerStack::analyze()
// This also calculates whether a contract is abstract, which is needed by the // This also calculates whether a contract is abstract, which is needed by the
// type checker. // type checker.
ContractLevelChecker contractLevelChecker(m_errorReporter); ContractLevelChecker contractLevelChecker(m_errorReporter);
for (Source const* source: m_sourceOrder) for (Source const* source: m_sourceOrder)
if (source->ast) if (auto sourceAst = source->ast)
for (ASTPointer<ASTNode> const& node: source->ast->nodes()) noErrors = contractLevelChecker.check(*sourceAst);
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
if (!contractLevelChecker.check(*contract))
noErrors = false;
// Requires ContractLevelChecker // Requires ContractLevelChecker
DocStringAnalyser docStringAnalyser(m_errorReporter); DocStringAnalyser docStringAnalyser(m_errorReporter);

View File

@ -800,7 +800,6 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
value, value,
visibility, visibility,
documentation, documentation,
_options.isStateVariable,
isIndexed, isIndexed,
mutability, mutability,
overrides, overrides,

View File

@ -226,7 +226,7 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False):
"3893", "3997", "4010", "4802", "4805", "4828", "3893", "3997", "4010", "4802", "4805", "4828",
"4904", "4990", "5052", "5073", "5170", "5188", "5272", "5333", "5347", "5473", "4904", "4990", "5052", "5073", "5170", "5188", "5272", "5333", "5347", "5473",
"5622", "6041", "6052", "6272", "6708", "6792", "6931", "7110", "7128", "7186", "5622", "6041", "6052", "6272", "6708", "6792", "6931", "7110", "7128", "7186",
"7319", "7589", "7593", "7653", "7812", "7885", "8065", "8084", "8140", "7589", "7593", "7653", "7812", "7885", "8065", "8084", "8140",
"8261", "8312", "8592", "8758", "9011", "8261", "8312", "8592", "8758", "9011",
"9085", "9390", "9440", "9547", "9551", "9615", "9980" "9085", "9390", "9440", "9547", "9551", "9615", "9980"
} }

View File

@ -123,6 +123,22 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
else else
assertThrow(false, Exception, "Unsupported EVM version"); assertThrow(false, Exception, "Unsupported EVM version");
tx_context.block_difficulty = evmc::uint256be{200000000};
tx_context.block_gas_limit = 20000000;
tx_context.block_coinbase = 0x7878787878787878787878787878787878787878_address;
tx_context.tx_gas_price = evmc::uint256be{3000000000};
tx_context.tx_origin = 0x9292929292929292929292929292929292929292_address;
// Mainnet according to EIP-155
tx_context.chain_id = evmc::uint256be{1};
reset();
}
void EVMHost::reset()
{
accounts.clear();
m_currentAddress = {};
// Mark all precompiled contracts as existing. Existing here means to have a balance (as per EIP-161). // Mark all precompiled contracts as existing. Existing here means to have a balance (as per EIP-161).
// NOTE: keep this in sync with `EVMHost::call` below. // NOTE: keep this in sync with `EVMHost::call` below.
// //
@ -131,19 +147,13 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
// roughly 22 days before the update went live. // roughly 22 days before the update went live.
for (unsigned precompiledAddress = 1; precompiledAddress <= 8; precompiledAddress++) for (unsigned precompiledAddress = 1; precompiledAddress <= 8; precompiledAddress++)
{ {
evmc::address address{}; evmc::address address{precompiledAddress};
address.bytes[19] = precompiledAddress;
// 1wei // 1wei
accounts[address].balance = evmc::uint256be{1}; accounts[address].balance = evmc::uint256be{1};
// Set according to EIP-1052.
if (precompiledAddress < 5 || m_evmVersion >= langutil::EVMVersion::byzantium())
accounts[address].codehash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470_bytes32;
} }
tx_context.block_difficulty = evmc::uint256be{200000000};
tx_context.block_gas_limit = 20000000;
tx_context.block_coinbase = 0x7878787878787878787878787878787878787878_address;
tx_context.tx_gas_price = evmc::uint256be{3000000000};
tx_context.tx_origin = 0x9292929292929292929292929292929292929292_address;
// Mainnet according to EIP-155
tx_context.chain_id = evmc::uint256be{1};
} }
void EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _beneficiary) noexcept void EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _beneficiary) noexcept

View File

@ -54,7 +54,7 @@ public:
explicit EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm); explicit EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm);
void reset() { accounts.clear(); m_currentAddress = {}; } void reset();
void newBlock() void newBlock()
{ {
tx_context.block_number++; tx_context.block_number++;

View File

@ -599,42 +599,6 @@ BOOST_AUTO_TEST_CASE(complex_import)
BOOST_CHECK(successParse(text)); BOOST_CHECK(successParse(text));
} }
BOOST_AUTO_TEST_CASE(recursion_depth1)
{
string text("contract C { bytes");
for (size_t i = 0; i < 30000; i++)
text += "[";
CHECK_PARSE_ERROR(text.c_str(), "Maximum recursion depth reached during parsing");
}
BOOST_AUTO_TEST_CASE(recursion_depth2)
{
string text("contract C { function f() {");
for (size_t i = 0; i < 30000; i++)
text += "{";
CHECK_PARSE_ERROR(text, "Maximum recursion depth reached during parsing");
}
BOOST_AUTO_TEST_CASE(recursion_depth3)
{
string text("contract C { function f() { uint x = f(");
for (size_t i = 0; i < 30000; i++)
text += "(";
CHECK_PARSE_ERROR(text, "Maximum recursion depth reached during parsing");
}
BOOST_AUTO_TEST_CASE(recursion_depth4)
{
string text("contract C { function f() { uint a;");
for (size_t i = 0; i < 30000; i++)
text += "(";
text += "a";
for (size_t i = 0; i < 30000; i++)
text += "++)";
text += "}}";
CHECK_PARSE_ERROR(text, "Maximum recursion depth reached during parsing");
}
BOOST_AUTO_TEST_CASE(inline_asm_end_location) BOOST_AUTO_TEST_CASE(inline_asm_end_location)
{ {
auto sourceCode = std::string(R"( auto sourceCode = std::string(R"(

View File

@ -0,0 +1,10 @@
function f() pure returns (uint) { return 1337; }
contract C {
function f() public pure returns (uint) {
return f();
}
}
// ====
// compileViaYul: also
// ----
// f() -> FAILURE

View File

@ -0,0 +1,15 @@
==== Source: s1.sol ====
import {f as g} from "s2.sol";
function f() pure returns (uint) { return 1; }
==== Source: s2.sol ====
import {f as g} from "s1.sol";
function f() pure returns (uint) { return 2; }
contract C {
function foo() public pure returns (uint) {
return f() - g();
}
}
// ====
// compileViaYul: also
// ----
// foo() -> 1

View File

@ -0,0 +1,14 @@
==== Source: s1.sol ====
import {f as g, g as h} from "s2.sol";
function f() pure returns (uint) { return h() - g(); }
==== Source: s2.sol ====
import {f as h} from "s1.sol";
function f() pure returns (uint) { return 2; }
function g() pure returns (uint) { return 4; }
contract C {
function foo() public pure returns (uint) {
return h() - f() - g();
}
}
// ----
// foo() -> -4

View File

@ -0,0 +1,16 @@
==== Source: s1.sol ====
import {f as g, g as h} from "s2.sol";
function f() pure returns (uint) { return h() - g(); }
==== Source: s2.sol ====
import {f as h} from "s1.sol";
function f() pure returns (uint) { return 2; }
function g() pure returns (uint) { return 4; }
==== Source: s3.sol ====
import "s1.sol";
contract C {
function foo() public pure returns (uint) {
return f() - g() - h();
}
}
// ----
// foo() -> -4

View File

@ -0,0 +1,16 @@
==== Source: s1.sol ====
import {f as g, g as h} from "s2.sol";
function f() pure returns (uint) { return h() - g(); }
==== Source: s2.sol ====
import {f as h} from "s1.sol";
function f() pure returns (uint) { return 2; }
function g() pure returns (uint) { return 4; }
==== Source: s3.sol ====
import "s2.sol";
contract C {
function foo() public pure returns (uint) {
return f() - g() - h();
}
}
// ----
// foo() -> -4

View File

@ -0,0 +1,14 @@
==== Source: s1.sol ====
function f(uint24) pure returns (uint) { return 24; }
function g(bool) pure returns (bool) { return true; }
==== Source: s2.sol ====
import {f as g, g as g} from "s1.sol";
contract C {
function foo() public pure returns (uint, bool) {
return (g(2), g(false));
}
}
// ====
// compileViaYul: also
// ----
// foo() -> 24, true

View File

@ -0,0 +1,18 @@
==== Source: s1.sol ====
function f() pure returns (uint) { return 1337; }
contract C {
function g() public pure returns (uint) {
return f();
}
}
==== Source: s2.sol ====
import "s1.sol";
contract D is C {
function h() public pure returns (uint) {
return g();
}
}
// ====
// compileViaYul: also
// ----
// h() -> 1337

View File

@ -0,0 +1,18 @@
==== Source: s1.sol ====
function f() pure returns (uint) { return 1337; }
contract C {
function g() public pure virtual returns (uint) {
return f() + 1;
}
}
==== Source: s2.sol ====
import "s1.sol";
contract D is C {
function g() public pure override returns (uint) {
return f();
}
}
// ====
// compileViaYul: also
// ----
// g() -> 1337

View File

@ -0,0 +1,18 @@
==== Source: s1.sol ====
function f() pure returns (uint) { return 1337; }
contract C {
function g() public pure virtual returns (uint) {
return f();
}
}
==== Source: s2.sol ====
import "s1.sol";
contract D is C {
function g() public pure override returns (uint) {
return super.g();
}
}
// ====
// compileViaYul: also
// ----
// g() -> 1337

View File

@ -0,0 +1,25 @@
==== Source: s1.sol ====
function f() pure returns (uint) { return 1337; }
contract C {
function g() public pure virtual returns (uint) {
return f();
}
}
==== Source: s2.sol ====
import "s1.sol";
contract D is C {
function g() public pure virtual override returns (uint) {
return super.g() + 1;
}
}
==== Source: s3.sol ====
import "s2.sol";
contract E is D {
function g() public pure override returns (uint) {
return super.g() + 1;
}
}
// ====
// compileViaYul: also
// ----
// g() -> 1339

View File

@ -0,0 +1,27 @@
==== Source: s1.sol ====
function f() pure returns (uint) { return 1337; }
contract C {
function g() public pure returns (uint) {
return f();
}
}
==== Source: s2.sol ====
import "s1.sol";
contract D is C {
function h() public pure returns (uint) {
return g();
}
}
==== Source: s3.sol ====
import "s2.sol";
import {f as f} from "s2.sol";
contract E is D {
function i() public pure returns (uint) {
return f();
}
}
// ====
// compileViaYul: also
// ----
// i() -> 1337

View File

@ -0,0 +1,19 @@
==== Source: s1.sol ====
function f() pure returns (uint) { return 1337; }
contract C {
function g() public pure virtual returns (uint) {
return f();
}
}
==== Source: s2.sol ====
import "s1.sol" as M;
function f() pure returns (uint) { return 6; }
contract D is M.C {
function g() public pure override returns (uint) {
return super.g() + f() * 10000;
}
}
// ====
// compileViaYul: also
// ----
// g() -> 61337

View File

@ -0,0 +1,14 @@
==== Source: s1.sol ====
function f() pure returns (uint) { return 1337; }
==== Source: s2.sol ====
import {f as g} from "s1.sol";
function f() pure returns (uint) { return 6; }
contract D {
function h() public pure returns (uint) {
return g() + f() * 10000;
}
}
// ====
// compileViaYul: also
// ----
// h() -> 61337

View File

@ -0,0 +1,15 @@
==== Source: s1.sol ====
function f() pure returns (uint) { return 1337; }
==== Source: s2.sol ====
import {f as g} from "s1.sol";
==== Source: s3.sol ====
import {g as h} from "s2.sol";
contract C {
function foo() public pure returns (uint) {
return h();
}
}
// ====
// compileViaYul: also
// ----
// foo() -> 1337

View File

@ -0,0 +1,28 @@
contract C {
constructor() payable {}
function f() public returns (uint256 ret) {
assembly {
ret := balance(0)
}
}
function g() public returns (uint256 ret) {
assembly {
ret := balance(1)
}
}
function h() public returns (uint256 ret) {
assembly {
ret := balance(address())
}
}
}
// ====
// EVMVersion: >=constantinople
// compileViaYul: also
// ----
// constructor(), 23 wei ->
// f() -> 0
// g() -> 1
// h() -> 23

View File

@ -0,0 +1,25 @@
contract C {
function f() public returns (bytes32 ret) {
assembly {
ret := extcodehash(0)
}
}
function g() public returns (bytes32 ret) {
assembly {
ret := extcodehash(1)
}
}
function h() public returns (bool ret) {
assembly {
ret := iszero(iszero(extcodehash(address())))
}
}
}
// ====
// EVMVersion: >=constantinople
// compileViaYul: also
// ----
// f() -> 0
// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
// h() -> true

View File

@ -8,4 +8,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 2529: (82-89): Empty array "pop" detected here. // Warning 2529: (82-89): CHC: Empty array "pop" detected here.

View File

@ -8,4 +8,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 2529: (82-89): Empty array "pop" detected here. // Warning 2529: (82-89): CHC: Empty array "pop" detected here.

View File

@ -8,5 +8,5 @@ contract C {
} }
} }
// ---- // ----
// Warning 2529: (82-89): Empty array "pop" detected here. // Warning 2529: (82-89): CHC: Empty array "pop" detected here.
// Warning 2529: (93-100): Empty array "pop" detected here. // Warning 2529: (93-100): CHC: Empty array "pop" detected here.

View File

@ -8,4 +8,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 2529: (94-101): Empty array "pop" detected here. // Warning 2529: (94-101): CHC: Empty array "pop" detected here.

View File

@ -11,4 +11,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 2529: (122-129): Empty array "pop" detected here. // Warning 2529: (122-129): CHC: Empty array "pop" detected here.

View File

@ -11,4 +11,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 2529: (127-134): Empty array "pop" detected here. // Warning 2529: (127-134): CHC: Empty array "pop" detected here.

View File

@ -13,4 +13,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 2529: (82-89): Empty array "pop" detected here. // Warning 2529: (82-89): CHC: Empty array "pop" detected here.

View File

@ -10,4 +10,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (153-176): Assertion violation happens here. // Warning 6328: (153-176): CHC: Assertion violation happens here.

View File

@ -14,6 +14,6 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (198-224): Assertion violation happens here. // Warning 6328: (198-224): CHC: Assertion violation happens here.
// Warning 6328: (228-254): Assertion violation happens here. // Warning 6328: (228-254): CHC: Assertion violation happens here.
// Warning 6328: (258-281): Assertion violation happens here. // Warning 6328: (258-281): CHC: Assertion violation happens here.

View File

@ -16,7 +16,7 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (222-248): Assertion violation happens here. // Warning 6328: (222-248): CHC: Assertion violation happens here.
// Warning 6328: (252-278): Assertion violation happens here. // Warning 6328: (252-278): CHC: Assertion violation happens here.
// Warning 6328: (282-305): Assertion violation happens here. // Warning 6328: (282-305): CHC: Assertion violation happens here.
// Warning 6328: (309-335): Assertion violation happens here. // Warning 6328: (309-335): CHC: Assertion violation happens here.

View File

@ -7,4 +7,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 2529: (82-89): Empty array "pop" detected here. // Warning 2529: (82-89): CHC: Empty array "pop" detected here.

View File

@ -9,4 +9,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 2529: (111-121): Empty array "pop" detected here. // Warning 2529: (111-121): CHC: Empty array "pop" detected here.

View File

@ -7,4 +7,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 2529: (76-83): Empty array "pop" detected here. // Warning 2529: (76-83): CHC: Empty array "pop" detected here.

View File

@ -11,4 +11,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 2529: (150-157): Empty array "pop" detected here. // Warning 2529: (150-157): CHC: Empty array "pop" detected here.

View File

@ -10,5 +10,5 @@ contract C {
} }
} }
// ---- // ----
// Warning 3944: (162-177): Underflow (resulting value less than 0) happens here. // Warning 3944: (162-177): CHC: Underflow (resulting value less than 0) happens here.
// Warning 6328: (150-184): Assertion violation happens here. // Warning 6328: (150-184): CHC: Assertion violation happens here.

View File

@ -8,5 +8,5 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (113-139): Assertion violation happens here. // Warning 6328: (113-139): CHC: Assertion violation happens here.
// Warning 6328: (143-189): Assertion violation happens here. // Warning 6328: (143-189): CHC: Assertion violation happens here.

View File

@ -10,6 +10,6 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (122-148): Assertion violation happens here. // Warning 6328: (122-148): CHC: Assertion violation happens here.
// Warning 6328: (202-218): Assertion violation happens here. // Warning 6328: (202-218): CHC: Assertion violation happens here.
// Warning 6328: (222-278): Assertion violation happens here. // Warning 6328: (222-278): CHC: Assertion violation happens here.

View File

@ -12,5 +12,5 @@ contract C {
} }
} }
// ---- // ----
// Warning 3944: (217-232): Underflow (resulting value less than 0) happens here. // Warning 3944: (217-232): CHC: Underflow (resulting value less than 0) happens here.
// Warning 6328: (205-239): Assertion violation happens here. // Warning 6328: (205-239): CHC: Assertion violation happens here.

View File

@ -12,4 +12,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (167-188): Assertion violation happens here. // Warning 6328: (167-188): CHC: Assertion violation happens here.

View File

@ -18,6 +18,6 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (193-217): Assertion violation happens here. // Warning 6328: (193-217): CHC: Assertion violation happens here.
// Warning 6328: (309-333): Assertion violation happens here. // Warning 6328: (309-333): CHC: Assertion violation happens here.
// Warning 6328: (419-436): Assertion violation happens here. // Warning 6328: (419-436): CHC: Assertion violation happens here.

View File

@ -9,4 +9,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (111-144): Assertion violation happens here. // Warning 6328: (111-144): CHC: Assertion violation happens here.

View File

@ -8,4 +8,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (94-124): Assertion violation happens here. // Warning 6328: (94-124): CHC: Assertion violation happens here.

View File

@ -15,4 +15,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (184-213): Assertion violation happens here. // Warning 6328: (184-213): CHC: Assertion violation happens here.

View File

@ -53,4 +53,4 @@ contract MyConc{
// ---- // ----
// Warning 2519: (773-792): This declaration shadows an existing declaration. // Warning 2519: (773-792): This declaration shadows an existing declaration.
// Warning 2018: (1009-1086): Function state mutability can be restricted to view // Warning 2018: (1009-1086): Function state mutability can be restricted to view
// Warning 4984: (985-1002): Overflow (resulting value larger than 2**256 - 1) happens here. // Warning 4984: (985-1002): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.

View File

@ -30,4 +30,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (448-465): Assertion violation happens here. // Warning 6328: (448-465): CHC: Assertion violation happens here.

View File

@ -32,4 +32,4 @@ contract C {
// ---- // ----
// Warning 5740: (116-129): Unreachable code. // Warning 5740: (116-129): Unreachable code.
// Warning 5740: (221-234): Unreachable code. // Warning 5740: (221-234): Unreachable code.
// Warning 6328: (427-444): Assertion violation happens here. // Warning 6328: (427-444): CHC: Assertion violation happens here.

View File

@ -14,5 +14,5 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (183-197): Assertion violation happens here. // Warning 6328: (183-197): CHC: Assertion violation happens here.
// Warning 6838: (155-156): Condition is always false. // Warning 6838: (155-156): BMC: Condition is always false.

View File

@ -15,4 +15,4 @@ contract c {
} }
} }
// ---- // ----
// Warning 6328: (227-236): Assertion violation happens here. // Warning 6328: (227-236): CHC: Assertion violation happens here.

View File

@ -17,5 +17,5 @@ contract c {
} }
} }
// ---- // ----
// Warning 6328: (202-218): Assertion violation happens here. // Warning 6328: (202-218): CHC: Assertion violation happens here.
// Warning 6328: (242-252): Assertion violation happens here. // Warning 6328: (242-252): CHC: Assertion violation happens here.

View File

@ -15,4 +15,4 @@ contract c {
} }
} }
// ---- // ----
// Warning 6328: (225-235): Assertion violation happens here. // Warning 6328: (225-235): CHC: Assertion violation happens here.

View File

@ -12,8 +12,8 @@ contract C
} }
} }
// ---- // ----
// Warning 6838: (84-110): Condition is always false. // Warning 6838: (84-110): BMC: Condition is always false.
// Warning 6838: (121-147): Condition is always true. // Warning 6838: (121-147): BMC: Condition is always true.
// Warning 6838: (158-183): Condition is always false. // Warning 6838: (158-183): BMC: Condition is always false.
// Warning 6838: (194-221): Condition is always false. // Warning 6838: (194-221): BMC: Condition is always false.
// Warning 6838: (232-247): Condition is always true. // Warning 6838: (232-247): BMC: Condition is always true.

View File

@ -16,8 +16,8 @@ contract C
} }
} }
// ---- // ----
// Warning 6838: (156-179): Condition is always false. // Warning 6838: (156-179): BMC: Condition is always false.
// Warning 6838: (190-213): Condition is always true. // Warning 6838: (190-213): BMC: Condition is always true.
// Warning 6838: (224-243): Condition is always false. // Warning 6838: (224-243): BMC: Condition is always false.
// Warning 6838: (254-277): Condition is always false. // Warning 6838: (254-277): BMC: Condition is always false.
// Warning 6838: (288-300): Condition is always true. // Warning 6838: (288-300): BMC: Condition is always true.

View File

@ -15,4 +15,4 @@ contract c {
} }
} }
// ---- // ----
// Warning 6328: (225-235): Assertion violation happens here. // Warning 6328: (225-235): CHC: Assertion violation happens here.

View File

@ -24,4 +24,4 @@ contract c {
} }
} }
// ---- // ----
// Warning 6328: (360-370): Assertion violation happens here. // Warning 6328: (360-370): CHC: Assertion violation happens here.

View File

@ -15,4 +15,4 @@ contract c {
} }
} }
// ---- // ----
// Warning 6328: (225-235): Assertion violation happens here. // Warning 6328: (225-235): CHC: Assertion violation happens here.

View File

@ -12,8 +12,8 @@ contract C
} }
} }
// ---- // ----
// Warning 6838: (84-110): Condition is always true. // Warning 6838: (84-110): BMC: Condition is always true.
// Warning 6838: (121-147): Condition is always true. // Warning 6838: (121-147): BMC: Condition is always true.
// Warning 6838: (158-183): Condition is always true. // Warning 6838: (158-183): BMC: Condition is always true.
// Warning 6838: (194-221): Condition is always true. // Warning 6838: (194-221): BMC: Condition is always true.
// Warning 6838: (232-248): Condition is always false. // Warning 6838: (232-248): BMC: Condition is always false.

View File

@ -16,8 +16,8 @@ contract C
} }
} }
// ---- // ----
// Warning 6838: (156-179): Condition is always true. // Warning 6838: (156-179): BMC: Condition is always true.
// Warning 6838: (190-213): Condition is always true. // Warning 6838: (190-213): BMC: Condition is always true.
// Warning 6838: (224-243): Condition is always true. // Warning 6838: (224-243): BMC: Condition is always true.
// Warning 6838: (254-277): Condition is always true. // Warning 6838: (254-277): BMC: Condition is always true.
// Warning 6838: (288-301): Condition is always false. // Warning 6838: (288-301): BMC: Condition is always false.

View File

@ -9,4 +9,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (159-173): Assertion violation happens here. // Warning 6328: (159-173): CHC: Assertion violation happens here.

View File

@ -9,4 +9,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (159-173): Assertion violation happens here. // Warning 6328: (159-173): CHC: Assertion violation happens here.

View File

@ -9,4 +9,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (161-175): Assertion violation happens here. // Warning 6328: (161-175): CHC: Assertion violation happens here.

View File

@ -17,4 +17,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (200-214): Assertion violation happens here. // Warning 6328: (200-214): CHC: Assertion violation happens here.

View File

@ -26,4 +26,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (423-445): Assertion violation happens here. // Warning 6328: (423-445): CHC: Assertion violation happens here.

View File

@ -28,4 +28,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (431-453): Assertion violation happens here. // Warning 6328: (431-453): CHC: Assertion violation happens here.

View File

@ -34,4 +34,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (528-565): Assertion violation happens here. // Warning 6328: (528-565): CHC: Assertion violation happens here.

View File

@ -29,4 +29,4 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (299-313): Assertion violation happens here. // Warning 6328: (299-313): CHC: Assertion violation happens here.

View File

@ -42,5 +42,5 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (452-466): Assertion violation happens here. // Warning 6328: (452-466): CHC: Assertion violation happens here.
// Warning 6328: (470-496): Assertion violation happens here. // Warning 6328: (470-496): CHC: Assertion violation happens here.

View File

@ -34,5 +34,5 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (381-395): Assertion violation happens here. // Warning 6328: (381-395): CHC: Assertion violation happens here.
// Warning 6328: (399-425): Assertion violation happens here. // Warning 6328: (399-425): CHC: Assertion violation happens here.

View File

@ -38,5 +38,5 @@ contract C {
} }
} }
// ---- // ----
// Warning 6328: (435-461): Assertion violation happens here. // Warning 6328: (435-461): CHC: Assertion violation happens here.
// Warning 6328: (594-631): Assertion violation happens here. // Warning 6328: (594-631): CHC: Assertion violation happens here.

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