2014-10-13 13:07:21 +00:00
/*
2016-11-18 23:13:20 +00:00
This file is part of solidity .
2014-10-13 13:07:21 +00:00
2016-11-18 23:13:20 +00:00
solidity is free software : you can redistribute it and / or modify
2014-10-13 13:07:21 +00:00
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
2016-11-18 23:13:20 +00:00
solidity is distributed in the hope that it will be useful ,
2014-10-13 13:07:21 +00:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2016-11-18 23:13:20 +00:00
along with solidity . If not , see < http : //www.gnu.org/licenses/>.
2014-10-13 13:07:21 +00:00
*/
/**
* @ author Christian < c @ ethdev . com >
* @ date 2014
* Unit tests for the name and type resolution of the solidity parser .
*/
2017-08-28 18:40:38 +00:00
# include <test/libsolidity/AnalysisFramework.h>
2017-03-03 11:51:51 +00:00
2018-03-14 11:04:04 +00:00
# include <test/Options.h>
2018-02-23 18:29:20 +00:00
2017-08-28 18:40:38 +00:00
# include <libsolidity/ast/AST.h>
2017-03-03 11:51:51 +00:00
# include <libdevcore/SHA3.h>
2017-08-28 18:40:38 +00:00
# include <boost/test/unit_test.hpp>
2017-03-03 11:51:51 +00:00
# include <string>
2014-10-13 13:07:21 +00:00
2015-01-23 15:37:06 +00:00
using namespace std ;
2014-10-16 12:08:54 +00:00
namespace dev
{
namespace solidity
{
namespace test
{
2014-10-13 13:07:21 +00:00
2017-08-28 18:40:38 +00:00
BOOST_FIXTURE_TEST_SUITE ( SolidityNameAndTypeResolution , AnalysisFramework )
2014-10-13 13:07:21 +00:00
BOOST_AUTO_TEST_CASE ( name_references )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
uint256 variable ;
2017-09-05 15:11:53 +00:00
function f ( uint256 ) public returns ( uint out ) { f ( variable ) ; test ; out ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-10-13 13:07:21 +00:00
}
BOOST_AUTO_TEST_CASE ( undeclared_name )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
uint256 variable ;
2017-09-05 15:11:53 +00:00
function f ( uint256 arg ) public {
2016-12-03 20:52:51 +00:00
f ( notfound ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , DeclarationError , " Undeclared identifier. " ) ;
2014-10-13 13:07:21 +00:00
}
2018-01-04 14:45:44 +00:00
BOOST_AUTO_TEST_CASE ( undeclared_name_is_not_fatal )
{
char const * text = R " (
contract test {
uint256 variable ;
function f ( uint256 arg ) public {
f ( notfound ) ;
f ( notfound ) ;
}
}
) " ;
2018-02-09 22:54:05 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , DeclarationError , ( vector < string > { " Undeclared identifier " , " Undeclared identifier " } ) ) ;
2018-01-04 14:45:44 +00:00
}
2014-10-15 13:54:41 +00:00
BOOST_AUTO_TEST_CASE ( reference_to_later_declaration )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function g ( ) public { f ( ) ; }
function f ( ) public { }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-10-15 13:54:41 +00:00
}
BOOST_AUTO_TEST_CASE ( type_inference_smoke_test )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( uint256 arg1 , uint32 arg2 ) public returns ( bool ret ) {
2016-12-03 20:52:51 +00:00
var x = arg1 + arg2 = = 8 ; ret = x ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-10-15 13:54:41 +00:00
}
BOOST_AUTO_TEST_CASE ( type_checking_return )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( bool r ) { return 1 > = 2 ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-10-15 13:54:41 +00:00
}
BOOST_AUTO_TEST_CASE ( type_checking_return_wrong_number )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( bool r1 , bool r2 ) { return 1 > = 2 ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Different number of arguments in return statement than in returns declaration. " ) ;
2014-10-15 13:54:41 +00:00
}
BOOST_AUTO_TEST_CASE ( type_checking_return_wrong_type )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( uint256 r ) { return 1 > = 2 ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Return argument type bool is not implicitly convertible to expected type (type of first return variable) uint256. " ) ;
2014-10-15 13:54:41 +00:00
}
BOOST_AUTO_TEST_CASE ( type_checking_function_call )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( bool ) { return g ( 12 , true ) = = 3 ; }
function g ( uint256 , bool ) public returns ( uint256 ) { }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-10-15 13:54:41 +00:00
}
2014-11-04 14:07:33 +00:00
BOOST_AUTO_TEST_CASE ( type_conversion_for_comparison )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public { uint32 ( 2 ) = = int64 ( 2 ) ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-11-04 14:07:33 +00:00
}
BOOST_AUTO_TEST_CASE ( type_conversion_for_comparison_invalid )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public { int32 ( 2 ) = = uint64 ( 2 ) ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Operator == not compatible with types int32 and uint64 " ) ;
2014-11-04 14:07:33 +00:00
}
2014-10-15 13:54:41 +00:00
BOOST_AUTO_TEST_CASE ( type_inference_explicit_conversion )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( int256 r ) { var x = int256 ( uint32 ( 2 ) ) ; return x ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-10-15 13:54:41 +00:00
}
2014-12-10 16:15:10 +00:00
BOOST_AUTO_TEST_CASE ( large_string_literal )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public { var x = " 123456789012345678901234567890123 " ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-12-10 16:15:10 +00:00
}
2014-11-21 18:14:56 +00:00
BOOST_AUTO_TEST_CASE ( balance )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function fun ( ) public {
2016-12-03 20:52:51 +00:00
uint256 x = address ( 0 ) . balance ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-11-21 18:14:56 +00:00
}
BOOST_AUTO_TEST_CASE ( balance_invalid )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function fun ( ) public {
2016-12-03 20:52:51 +00:00
address ( 0 ) . balance = 7 ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Expression has to be an lvalue. " ) ;
2014-11-21 18:14:56 +00:00
}
2014-12-01 16:32:10 +00:00
BOOST_AUTO_TEST_CASE ( assignment_to_mapping )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
struct str {
mapping ( uint = > uint ) map ;
}
str data ;
2017-09-05 15:11:53 +00:00
function fun ( ) public {
2016-12-03 20:52:51 +00:00
var a = data . map ;
data . map = a ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Mappings cannot be assigned to. " ) ;
2014-12-01 16:32:10 +00:00
}
BOOST_AUTO_TEST_CASE ( assignment_to_struct )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
struct str {
mapping ( uint = > uint ) map ;
}
str data ;
2017-09-05 15:11:53 +00:00
function fun ( ) public {
2016-12-03 20:52:51 +00:00
var a = data ;
data = a ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-12-01 16:32:10 +00:00
}
2014-12-15 15:09:50 +00:00
BOOST_AUTO_TEST_CASE ( returns_in_constructor )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function test ( ) public returns ( uint a ) { }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Non-empty \" returns \" directive for constructor. " ) ;
2014-12-15 15:09:50 +00:00
}
2014-12-16 22:45:24 +00:00
BOOST_AUTO_TEST_CASE ( forward_function_reference )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract First {
2017-09-05 15:11:53 +00:00
function fun ( ) public returns ( bool ) {
2016-12-03 20:52:51 +00:00
return Second ( 1 ) . fun ( 1 , true , 3 ) > 0 ;
}
}
contract Second {
2017-09-05 15:11:53 +00:00
function fun ( uint , bool , uint ) public returns ( uint ) {
2016-12-03 20:52:51 +00:00
if ( First ( 2 ) . fun ( ) = = true ) return 1 ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-12-16 22:45:24 +00:00
}
2014-12-18 16:04:20 +00:00
BOOST_AUTO_TEST_CASE ( comparison_bitop_precedence )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract First {
2017-09-05 15:11:53 +00:00
function fun ( ) public returns ( bool ret ) {
2016-12-03 20:52:51 +00:00
return 1 & 2 = = 8 & 9 & & 1 ^ 2 < 4 | 6 ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-12-18 16:04:20 +00:00
}
2017-06-23 16:36:56 +00:00
BOOST_AUTO_TEST_CASE ( comparison_of_function_types )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( bool ret ) {
2017-06-23 16:36:56 +00:00
return this . f < this . f ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Operator < not compatible " ) ;
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( bool ret ) {
2017-06-23 16:36:56 +00:00
return f < f ;
}
}
) " ;
2017-06-26 21:01:35 +00:00
CHECK_ERROR ( text , TypeError , " Operator < not compatible " ) ;
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( bool ret ) {
2017-06-26 21:01:35 +00:00
return f = = f ;
}
2017-09-05 15:11:53 +00:00
function g ( ) public returns ( bool ret ) {
2017-06-26 21:01:35 +00:00
return f ! = f ;
}
}
) " ;
2017-06-23 16:36:56 +00:00
CHECK_SUCCESS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( comparison_of_mapping_types )
{
char const * text = R " (
contract C {
mapping ( uint = > uint ) x ;
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( bool ret ) {
2017-06-23 16:36:56 +00:00
var y = x ;
return x = = y ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Operator == not compatible " ) ;
}
2015-03-20 16:50:26 +00:00
BOOST_AUTO_TEST_CASE ( function_no_implementation )
{
2017-08-28 18:40:38 +00:00
SourceUnit const * sourceUnit = nullptr ;
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function functionName ( bytes32 input ) public returns ( bytes32 out ) ;
2016-12-03 20:52:51 +00:00
}
) " ;
2017-08-28 18:40:38 +00:00
sourceUnit = parseAndAnalyse ( text ) ;
2015-08-31 16:44:29 +00:00
std : : vector < ASTPointer < ASTNode > > nodes = sourceUnit - > nodes ( ) ;
2016-08-19 17:57:21 +00:00
ContractDefinition * contract = dynamic_cast < ContractDefinition * > ( nodes [ 1 ] . get ( ) ) ;
BOOST_REQUIRE ( contract ) ;
2017-08-02 10:58:22 +00:00
BOOST_CHECK ( ! contract - > annotation ( ) . unimplementedFunctions . empty ( ) ) ;
2015-09-16 14:56:30 +00:00
BOOST_CHECK ( ! contract - > definedFunctions ( ) [ 0 ] - > isImplemented ( ) ) ;
2015-03-20 16:50:26 +00:00
}
2015-03-27 14:15:34 +00:00
BOOST_AUTO_TEST_CASE ( abstract_contract )
{
2017-08-28 18:40:38 +00:00
SourceUnit const * sourceUnit = nullptr ;
2015-03-27 14:15:34 +00:00
char const * text = R " (
contract base { function foo ( ) ; }
2017-09-05 15:11:53 +00:00
contract derived is base { function foo ( ) public { } }
2016-12-03 20:52:51 +00:00
) " ;
2017-08-28 18:40:38 +00:00
sourceUnit = parseAndAnalyse ( text ) ;
2015-08-31 16:44:29 +00:00
std : : vector < ASTPointer < ASTNode > > nodes = sourceUnit - > nodes ( ) ;
2016-08-19 17:57:21 +00:00
ContractDefinition * base = dynamic_cast < ContractDefinition * > ( nodes [ 1 ] . get ( ) ) ;
ContractDefinition * derived = dynamic_cast < ContractDefinition * > ( nodes [ 2 ] . get ( ) ) ;
BOOST_REQUIRE ( base ) ;
2017-08-02 10:58:22 +00:00
BOOST_CHECK ( ! base - > annotation ( ) . unimplementedFunctions . empty ( ) ) ;
2015-09-16 14:56:30 +00:00
BOOST_CHECK ( ! base - > definedFunctions ( ) [ 0 ] - > isImplemented ( ) ) ;
2016-08-19 17:57:21 +00:00
BOOST_REQUIRE ( derived ) ;
2017-08-02 10:58:22 +00:00
BOOST_CHECK ( derived - > annotation ( ) . unimplementedFunctions . empty ( ) ) ;
2015-09-16 14:56:30 +00:00
BOOST_CHECK ( derived - > definedFunctions ( ) [ 0 ] - > isImplemented ( ) ) ;
2015-03-27 14:15:34 +00:00
}
2015-06-23 14:56:59 +00:00
BOOST_AUTO_TEST_CASE ( abstract_contract_with_overload )
{
2017-08-28 18:40:38 +00:00
SourceUnit const * sourceUnit = nullptr ;
2015-06-23 14:56:59 +00:00
char const * text = R " (
contract base { function foo ( bool ) ; }
2017-09-05 15:11:53 +00:00
contract derived is base { function foo ( uint ) public { } }
2016-12-03 20:52:51 +00:00
) " ;
2017-08-28 18:40:38 +00:00
sourceUnit = parseAndAnalyse ( text ) ;
2015-08-31 16:44:29 +00:00
std : : vector < ASTPointer < ASTNode > > nodes = sourceUnit - > nodes ( ) ;
2016-08-19 17:57:21 +00:00
ContractDefinition * base = dynamic_cast < ContractDefinition * > ( nodes [ 1 ] . get ( ) ) ;
ContractDefinition * derived = dynamic_cast < ContractDefinition * > ( nodes [ 2 ] . get ( ) ) ;
2015-06-23 14:56:59 +00:00
BOOST_REQUIRE ( base ) ;
2017-08-02 10:58:22 +00:00
BOOST_CHECK ( ! base - > annotation ( ) . unimplementedFunctions . empty ( ) ) ;
2015-06-23 14:56:59 +00:00
BOOST_REQUIRE ( derived ) ;
2017-08-02 10:58:22 +00:00
BOOST_CHECK ( ! derived - > annotation ( ) . unimplementedFunctions . empty ( ) ) ;
2015-06-23 14:56:59 +00:00
}
2015-03-27 14:15:34 +00:00
BOOST_AUTO_TEST_CASE ( create_abstract_contract )
{
char const * text = R " (
contract base { function foo ( ) ; }
2015-03-30 15:18:38 +00:00
contract derived {
2015-03-27 14:15:34 +00:00
base b ;
2017-09-05 15:11:53 +00:00
function foo ( ) public { b = new base ( ) ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Trying to create an instance of an abstract contract. " ) ;
2015-03-27 14:15:34 +00:00
}
BOOST_AUTO_TEST_CASE ( redeclare_implemented_abstract_function_as_abstract )
{
char const * text = R " (
contract base { function foo ( ) ; }
2017-09-05 15:11:53 +00:00
contract derived is base { function foo ( ) public { } }
2015-03-27 14:15:34 +00:00
contract wrong is derived { function foo ( ) ; }
2016-12-03 20:52:51 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Redeclaring an already implemented function as abstract " ) ;
2015-03-27 14:15:34 +00:00
}
2016-06-06 17:35:55 +00:00
BOOST_AUTO_TEST_CASE ( implement_abstract_via_constructor )
{
2017-08-28 18:40:38 +00:00
SourceUnit const * sourceUnit = nullptr ;
2016-06-06 17:35:55 +00:00
char const * text = R " (
contract base { function foo ( ) ; }
2017-09-05 15:11:53 +00:00
contract foo is base { function foo ( ) public { } }
2016-06-06 17:35:55 +00:00
) " ;
2017-08-28 18:40:38 +00:00
sourceUnit = parseAndAnalyse ( text ) ;
2016-06-06 17:35:55 +00:00
std : : vector < ASTPointer < ASTNode > > nodes = sourceUnit - > nodes ( ) ;
2016-08-19 17:57:21 +00:00
BOOST_CHECK_EQUAL ( nodes . size ( ) , 3 ) ;
ContractDefinition * derived = dynamic_cast < ContractDefinition * > ( nodes [ 2 ] . get ( ) ) ;
BOOST_REQUIRE ( derived ) ;
2017-08-02 10:58:22 +00:00
BOOST_CHECK ( ! derived - > annotation ( ) . unimplementedFunctions . empty ( ) ) ;
2016-06-06 17:35:55 +00:00
}
2015-01-07 01:07:34 +00:00
BOOST_AUTO_TEST_CASE ( function_canonical_signature )
{
2017-08-28 18:40:38 +00:00
SourceUnit const * sourceUnit = nullptr ;
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract Test {
2017-09-05 15:11:53 +00:00
function foo ( uint256 arg1 , uint64 arg2 , bool arg3 ) public returns ( uint256 ret ) {
2016-12-03 20:52:51 +00:00
ret = arg1 + arg2 ;
}
}
) " ;
2017-08-28 18:40:38 +00:00
sourceUnit = parseAndAnalyse ( text ) ;
2015-08-31 16:44:29 +00:00
for ( ASTPointer < ASTNode > const & node : sourceUnit - > nodes ( ) )
2015-01-07 01:07:34 +00:00
if ( ContractDefinition * contract = dynamic_cast < ContractDefinition * > ( node . get ( ) ) )
{
2015-08-31 16:44:29 +00:00
auto functions = contract - > definedFunctions ( ) ;
2015-03-24 10:11:27 +00:00
BOOST_CHECK_EQUAL ( " foo(uint256,uint64,bool) " , functions [ 0 ] - > externalSignature ( ) ) ;
2015-01-07 09:45:59 +00:00
}
}
BOOST_AUTO_TEST_CASE ( function_canonical_signature_type_aliases )
{
2017-08-28 18:40:38 +00:00
SourceUnit const * sourceUnit = nullptr ;
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract Test {
2017-09-05 15:11:53 +00:00
function boo ( uint , bytes32 , address ) public returns ( uint ret ) {
2016-12-03 20:52:51 +00:00
ret = 5 ;
}
}
) " ;
2017-08-28 18:40:38 +00:00
sourceUnit = parseAndAnalyse ( text ) ;
2015-08-31 16:44:29 +00:00
for ( ASTPointer < ASTNode > const & node : sourceUnit - > nodes ( ) )
2015-01-07 09:45:59 +00:00
if ( ContractDefinition * contract = dynamic_cast < ContractDefinition * > ( node . get ( ) ) )
{
2015-08-31 16:44:29 +00:00
auto functions = contract - > definedFunctions ( ) ;
2015-03-25 12:58:15 +00:00
if ( functions . empty ( ) )
continue ;
2015-03-24 10:11:27 +00:00
BOOST_CHECK_EQUAL ( " boo(uint256,bytes32,address) " , functions [ 0 ] - > externalSignature ( ) ) ;
2015-01-07 01:07:34 +00:00
}
}
2015-03-23 17:08:45 +00:00
BOOST_AUTO_TEST_CASE ( function_external_types )
{
2017-08-28 18:40:38 +00:00
SourceUnit const * sourceUnit = nullptr ;
2015-03-23 17:08:45 +00:00
char const * text = R " (
2015-03-25 12:58:15 +00:00
contract C {
uint a ;
}
2015-03-23 17:08:45 +00:00
contract Test {
2017-04-14 14:48:59 +00:00
function boo ( uint , bool , bytes8 , bool [ 2 ] , uint [ ] , C , address [ ] ) external returns ( uint ret ) {
2016-12-03 20:52:51 +00:00
ret = 5 ;
2015-03-23 17:08:45 +00:00
}
2016-12-03 20:52:51 +00:00
}
) " ;
2017-08-28 18:40:38 +00:00
sourceUnit = parseAndAnalyse ( text ) ;
2015-08-31 16:44:29 +00:00
for ( ASTPointer < ASTNode > const & node : sourceUnit - > nodes ( ) )
2015-03-23 17:08:45 +00:00
if ( ContractDefinition * contract = dynamic_cast < ContractDefinition * > ( node . get ( ) ) )
{
2015-08-31 16:44:29 +00:00
auto functions = contract - > definedFunctions ( ) ;
2015-03-25 12:58:15 +00:00
if ( functions . empty ( ) )
continue ;
2015-03-30 12:34:38 +00:00
BOOST_CHECK_EQUAL ( " boo(uint256,bool,bytes8,bool[2],uint256[],address,address[]) " , functions [ 0 ] - > externalSignature ( ) ) ;
2015-03-23 17:08:45 +00:00
}
}
2015-05-11 11:47:21 +00:00
BOOST_AUTO_TEST_CASE ( enum_external_type )
{
// bug #1801
2017-08-28 18:40:38 +00:00
SourceUnit const * sourceUnit = nullptr ;
2015-05-11 11:47:21 +00:00
char const * text = R " (
contract Test {
enum ActionChoices { GoLeft , GoRight , GoStraight , Sit }
function boo ( ActionChoices enumArg ) external returns ( uint ret ) {
2015-05-11 14:24:04 +00:00
ret = 5 ;
2015-05-11 11:47:21 +00:00
}
2016-12-03 20:52:51 +00:00
}
) " ;
2017-08-28 18:40:38 +00:00
sourceUnit = parseAndAnalyse ( text ) ;
2015-08-31 16:44:29 +00:00
for ( ASTPointer < ASTNode > const & node : sourceUnit - > nodes ( ) )
2015-05-11 11:47:21 +00:00
if ( ContractDefinition * contract = dynamic_cast < ContractDefinition * > ( node . get ( ) ) )
{
2015-08-31 16:44:29 +00:00
auto functions = contract - > definedFunctions ( ) ;
2015-05-11 11:47:21 +00:00
if ( functions . empty ( ) )
continue ;
BOOST_CHECK_EQUAL ( " boo(uint8) " , functions [ 0 ] - > externalSignature ( ) ) ;
}
}
2017-06-08 09:14:58 +00:00
BOOST_AUTO_TEST_CASE ( external_structs )
{
2017-06-09 16:28:13 +00:00
char const * text = R " (
2017-12-11 02:39:39 +00:00
pragma experimental ABIEncoderV2 ;
2017-06-09 16:28:13 +00:00
contract Test {
enum ActionChoices { GoLeft , GoRight , GoStraight , Sit }
struct Empty { }
2017-09-14 15:03:59 +00:00
struct Nested { X [ 2 ] [ ] a ; uint y ; }
2017-06-09 16:28:13 +00:00
struct X { bytes32 x ; Test t ; Empty [ ] e ; }
function f ( ActionChoices , uint , Empty ) external { }
2017-06-13 08:51:49 +00:00
function g ( Test , Nested ) external { }
2017-06-09 16:28:13 +00:00
function h ( function ( Nested ) external returns ( uint ) [ ] ) external { }
function i ( Nested [ ] ) external { }
}
) " ;
2017-09-01 11:37:40 +00:00
SourceUnit const * sourceUnit = parseAndAnalyse ( text ) ;
2017-06-09 16:28:13 +00:00
for ( ASTPointer < ASTNode > const & node : sourceUnit - > nodes ( ) )
if ( ContractDefinition * contract = dynamic_cast < ContractDefinition * > ( node . get ( ) ) )
{
auto functions = contract - > definedFunctions ( ) ;
BOOST_REQUIRE ( ! functions . empty ( ) ) ;
BOOST_CHECK_EQUAL ( " f(uint8,uint256,()) " , functions [ 0 ] - > externalSignature ( ) ) ;
2017-06-13 08:51:49 +00:00
BOOST_CHECK_EQUAL ( " g(address,((bytes32,address,()[])[2][],uint256)) " , functions [ 1 ] - > externalSignature ( ) ) ;
2017-06-09 16:28:13 +00:00
BOOST_CHECK_EQUAL ( " h(function[]) " , functions [ 2 ] - > externalSignature ( ) ) ;
BOOST_CHECK_EQUAL ( " i(((bytes32,address,()[])[2][],uint256)[]) " , functions [ 3 ] - > externalSignature ( ) ) ;
}
2017-06-08 09:14:58 +00:00
}
2017-09-01 11:37:40 +00:00
BOOST_AUTO_TEST_CASE ( external_structs_in_libraries )
{
char const * text = R " (
2017-12-11 02:39:39 +00:00
pragma experimental ABIEncoderV2 ;
2017-09-01 11:37:40 +00:00
library Test {
enum ActionChoices { GoLeft , GoRight , GoStraight , Sit }
struct Empty { }
2017-09-14 15:03:59 +00:00
struct Nested { X [ 2 ] [ ] a ; uint y ; }
2017-09-01 11:37:40 +00:00
struct X { bytes32 x ; Test t ; Empty [ ] e ; }
function f ( ActionChoices , uint , Empty ) external { }
function g ( Test , Nested ) external { }
function h ( function ( Nested ) external returns ( uint ) [ ] ) external { }
function i ( Nested [ ] ) external { }
}
) " ;
SourceUnit const * sourceUnit = parseAndAnalyse ( text ) ;
for ( ASTPointer < ASTNode > const & node : sourceUnit - > nodes ( ) )
if ( ContractDefinition * contract = dynamic_cast < ContractDefinition * > ( node . get ( ) ) )
{
auto functions = contract - > definedFunctions ( ) ;
BOOST_REQUIRE ( ! functions . empty ( ) ) ;
BOOST_CHECK_EQUAL ( " f(Test.ActionChoices,uint256,Test.Empty) " , functions [ 0 ] - > externalSignature ( ) ) ;
BOOST_CHECK_EQUAL ( " g(Test,Test.Nested) " , functions [ 1 ] - > externalSignature ( ) ) ;
BOOST_CHECK_EQUAL ( " h(function[]) " , functions [ 2 ] - > externalSignature ( ) ) ;
BOOST_CHECK_EQUAL ( " i(Test.Nested[]) " , functions [ 3 ] - > externalSignature ( ) ) ;
}
}
2017-09-14 15:03:59 +00:00
BOOST_AUTO_TEST_CASE ( struct_with_mapping_in_library )
{
char const * text = R " (
library Test {
struct Nested { mapping ( uint = > uint ) [ 2 ] [ ] a ; uint y ; }
struct X { Nested n ; }
function f ( X storage x ) external { }
}
) " ;
SourceUnit const * sourceUnit = parseAndAnalyse ( text ) ;
for ( ASTPointer < ASTNode > const & node : sourceUnit - > nodes ( ) )
if ( ContractDefinition * contract = dynamic_cast < ContractDefinition * > ( node . get ( ) ) )
{
auto functions = contract - > definedFunctions ( ) ;
BOOST_REQUIRE ( ! functions . empty ( ) ) ;
BOOST_CHECK_EQUAL ( " f(Test.X storage) " , functions [ 0 ] - > externalSignature ( ) ) ;
}
}
BOOST_AUTO_TEST_CASE ( functions_with_identical_structs_in_interface )
{
char const * text = R " (
pragma experimental ABIEncoderV2 ;
contract C {
struct S1 { }
struct S2 { }
function f ( S1 ) pure { }
function f ( S2 ) pure { }
}
) " ;
CHECK_ERROR ( text , TypeError , " Function overload clash during conversion to external types for arguments " ) ;
}
BOOST_AUTO_TEST_CASE ( functions_with_different_structs_in_interface )
{
char const * text = R " (
pragma experimental ABIEncoderV2 ;
contract C {
struct S1 { function ( ) external a ; }
struct S2 { bytes24 a ; }
function f ( S1 ) pure { }
function f ( S2 ) pure { }
}
) " ;
CHECK_SUCCESS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( functions_with_stucts_of_non_external_types_in_interface )
{
char const * text = R " (
pragma experimental ABIEncoderV2 ;
contract C {
struct S { function ( ) internal a ; }
function f ( S ) { }
}
) " ;
CHECK_ERROR ( text , TypeError , " Internal or recursive type is not allowed for public or external functions. " ) ;
}
BOOST_AUTO_TEST_CASE ( functions_with_stucts_of_non_external_types_in_interface_2 )
{
char const * text = R " (
pragma experimental ABIEncoderV2 ;
contract C {
struct S { mapping ( uint = > uint ) a ; }
function f ( S ) { }
}
) " ;
CHECK_ERROR ( text , TypeError , " Internal or recursive type is not allowed for public or external functions. " ) ;
}
BOOST_AUTO_TEST_CASE ( functions_with_stucts_of_non_external_types_in_interface_nested )
{
char const * text = R " (
pragma experimental ABIEncoderV2 ;
contract C {
struct T { mapping ( uint = > uint ) a ; }
struct S { T [ ] [ 2 ] b ; }
function f ( S ) { }
}
) " ;
CHECK_ERROR ( text , TypeError , " Internal or recursive type is not allowed for public or external functions. " ) ;
}
2017-06-09 16:28:13 +00:00
2018-02-19 17:20:49 +00:00
BOOST_AUTO_TEST_CASE ( returning_multi_dimensional_arrays_new_abi )
{
char const * text = R " (
pragma experimental ABIEncoderV2 ;
contract C {
function f ( ) public pure returns ( string [ ] [ ] ) { }
}
) " ;
CHECK_WARNING ( text , " Experimental features " ) ;
}
BOOST_AUTO_TEST_CASE ( returning_multi_dimensional_arrays )
{
char const * text = R " (
contract C {
function f ( ) public pure returns ( string [ ] [ ] ) { }
}
) " ;
CHECK_ERROR ( text , TypeError , " only supported in the new experimental ABI encoder " ) ;
}
BOOST_AUTO_TEST_CASE ( returning_multi_dimensional_static_arrays )
{
char const * text = R " (
contract C {
function f ( ) public pure returns ( uint [ ] [ 2 ] ) { }
}
) " ;
CHECK_ERROR ( text , TypeError , " only supported in the new experimental ABI encoder " ) ;
}
BOOST_AUTO_TEST_CASE ( returning_arrays_in_structs_new_abi )
{
char const * text = R " (
pragma experimental ABIEncoderV2 ;
contract C {
struct S { string [ ] s ; }
function f ( ) public pure returns ( S ) { }
}
) " ;
CHECK_WARNING ( text , " Experimental features " ) ;
}
BOOST_AUTO_TEST_CASE ( returning_arrays_in_structs_arrays )
{
char const * text = R " (
contract C {
struct S { string [ ] s ; }
function f ( ) public pure returns ( S x ) { }
}
) " ;
CHECK_ERROR ( text , TypeError , " only supported in the new experimental ABI encoder " ) ;
}
2015-03-26 13:11:24 +00:00
BOOST_AUTO_TEST_CASE ( function_external_call_allowed_conversion )
2015-03-25 12:58:15 +00:00
{
2015-03-26 13:11:24 +00:00
char const * text = R " (
contract C { }
contract Test {
2017-09-05 15:11:53 +00:00
function externalCall ( ) public {
2015-03-26 13:11:24 +00:00
C arg ;
this . g ( arg ) ;
}
function g ( C c ) external { }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-03-26 13:11:24 +00:00
}
BOOST_AUTO_TEST_CASE ( function_external_call_not_allowed_conversion )
{
char const * text = R " (
2015-03-25 12:58:15 +00:00
contract C { }
contract Test {
2017-09-05 15:11:53 +00:00
function externalCall ( ) public {
2015-03-25 12:58:15 +00:00
address arg ;
this . g ( arg ) ;
}
function g ( C c ) external { }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Invalid type for argument in function call. Invalid implicit conversion from address to contract C requested. " ) ;
2015-03-26 13:11:24 +00:00
}
BOOST_AUTO_TEST_CASE ( function_internal_allowed_conversion )
{
char const * text = R " (
contract C {
uint a ;
}
contract Test {
C a ;
2017-09-05 15:11:53 +00:00
function g ( C c ) public { }
function internalCall ( ) public {
2015-03-26 13:11:24 +00:00
g ( a ) ;
}
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-03-25 12:58:15 +00:00
}
2015-03-26 13:11:24 +00:00
BOOST_AUTO_TEST_CASE ( function_internal_not_allowed_conversion )
2015-03-25 12:58:15 +00:00
{
char const * text = R " (
contract C {
uint a ;
}
contract Test {
address a ;
2017-09-05 15:11:53 +00:00
function g ( C c ) public { }
function internalCall ( ) public {
2015-03-25 12:58:15 +00:00
g ( a ) ;
}
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Invalid type for argument in function call. Invalid implicit conversion from address to contract C requested. " ) ;
2015-03-25 12:58:15 +00:00
}
2015-03-23 17:08:45 +00:00
2015-01-14 09:16:58 +00:00
BOOST_AUTO_TEST_CASE ( hash_collision_in_interface )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function gsf ( ) public { }
function tgeo ( ) public { }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Function signature hash collision for tgeo() " ) ;
2015-01-14 09:16:58 +00:00
}
2015-01-15 19:04:06 +00:00
BOOST_AUTO_TEST_CASE ( inheritance_basic )
{
char const * text = R " (
contract base { uint baseMember ; struct BaseType { uint element ; } }
contract derived is base {
BaseType data ;
2017-09-05 15:11:53 +00:00
function f ( ) public { baseMember = 7 ; }
2015-01-15 19:04:06 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-15 19:04:06 +00:00
}
BOOST_AUTO_TEST_CASE ( inheritance_diamond_basic )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract root { function rootFunction ( ) public { } }
contract inter1 is root { function f ( ) public { } }
contract inter2 is root { function f ( ) public { } }
2015-01-26 09:20:46 +00:00
contract derived is root , inter2 , inter1 {
2017-09-05 15:11:53 +00:00
function g ( ) public { f ( ) ; rootFunction ( ) ; }
2015-01-15 19:04:06 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-15 19:04:06 +00:00
}
BOOST_AUTO_TEST_CASE ( cyclic_inheritance )
{
char const * text = R " (
contract A is B { }
contract B is A { }
) " ;
2018-02-09 22:54:05 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , ( vector < string > { " Definition of base has to precede definition of derived contract " } ) ) ;
2015-01-15 19:04:06 +00:00
}
2015-02-28 08:29:32 +00:00
BOOST_AUTO_TEST_CASE ( legal_override_direct )
2015-01-16 16:50:10 +00:00
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract B { function f ( ) public { } }
contract C is B { function f ( uint i ) public { } }
2015-01-16 16:50:10 +00:00
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-16 16:50:10 +00:00
}
2015-02-28 08:29:32 +00:00
BOOST_AUTO_TEST_CASE ( legal_override_indirect )
2015-01-16 16:50:10 +00:00
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract A { function f ( uint a ) public { } }
contract B { function f ( ) public { } }
2015-01-16 16:50:10 +00:00
contract C is A , B { }
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-16 16:50:10 +00:00
}
2015-02-02 16:24:09 +00:00
BOOST_AUTO_TEST_CASE ( illegal_override_visibility )
{
char const * text = R " (
2015-02-22 18:37:54 +00:00
contract B { function f ( ) internal { } }
2015-02-02 16:24:09 +00:00
contract C is B { function f ( ) public { } }
) " ;
2017-07-18 04:10:57 +00:00
CHECK_ERROR ( text , TypeError , " Overriding function visibility differs " ) ;
2015-02-02 16:24:09 +00:00
}
2017-07-18 04:10:57 +00:00
BOOST_AUTO_TEST_CASE ( illegal_override_remove_constness )
2015-02-02 16:24:09 +00:00
{
char const * text = R " (
contract B { function f ( ) constant { } }
2017-09-05 15:11:53 +00:00
contract C is B { function f ( ) public { } }
2015-02-02 16:24:09 +00:00
) " ;
2017-08-15 23:29:59 +00:00
CHECK_ERROR ( text , TypeError , " Overriding function changes state mutability from \" view \" to \" nonpayable \" . " ) ;
2017-07-18 04:10:57 +00:00
}
BOOST_AUTO_TEST_CASE ( illegal_override_add_constness )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract B { function f ( ) public { } }
2017-07-18 04:10:57 +00:00
contract C is B { function f ( ) constant { } }
) " ;
2017-08-15 23:29:59 +00:00
CHECK_ERROR ( text , TypeError , " Overriding function changes state mutability from \" nonpayable \" to \" view \" . " ) ;
2015-02-02 16:24:09 +00:00
}
2015-01-16 16:50:10 +00:00
BOOST_AUTO_TEST_CASE ( complex_inheritance )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract A { function f ( ) public { uint8 x = C ( 0 ) . g ( ) ; } }
contract B { function f ( ) public { } function g ( ) public returns ( uint8 ) { } }
2015-01-16 16:50:10 +00:00
contract C is A , B { }
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-16 16:50:10 +00:00
}
BOOST_AUTO_TEST_CASE ( constructor_visibility )
{
// The constructor of a base class should not be visible in the derived class
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract A { function A ( ) public { } }
contract B is A { function f ( ) public { A x = A ( 0 ) ; } }
2015-01-16 16:50:10 +00:00
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-16 16:50:10 +00:00
}
BOOST_AUTO_TEST_CASE ( overriding_constructor )
{
// It is fine to "override" constructor of a base class since it is invisible
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract A { function A ( ) public { } }
contract B is A { function A ( ) public returns ( uint8 r ) { } }
2015-01-16 16:50:10 +00:00
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-16 16:50:10 +00:00
}
2015-01-19 22:08:48 +00:00
BOOST_AUTO_TEST_CASE ( missing_base_constructor_arguments )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract A { function A ( uint a ) public { } }
2015-01-19 22:08:48 +00:00
contract B is A { }
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-19 22:08:48 +00:00
}
BOOST_AUTO_TEST_CASE ( base_constructor_arguments_override )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract A { function A ( uint a ) public { } }
2015-01-19 22:08:48 +00:00
contract B is A { }
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-19 22:08:48 +00:00
}
2018-03-01 17:39:01 +00:00
BOOST_AUTO_TEST_CASE ( new_constructor_syntax )
{
char const * text = R " (
contract A { constructor ( ) public { } }
) " ;
2018-03-05 15:35:31 +00:00
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2018-03-01 17:39:01 +00:00
}
BOOST_AUTO_TEST_CASE ( old_constructor_syntax )
{
char const * text = R " (
contract A { function A ( ) public { } }
) " ;
CHECK_WARNING (
text ,
" Defining constructors as functions with the same name as the contract is deprecated. "
) ;
text = R " (
pragma experimental " v0.5.0 " ;
contract A { function A ( ) public { } }
) " ;
CHECK_ERROR (
text ,
SyntaxError ,
" Functions are not allowed to have the same name as the contract. "
) ;
}
2015-01-19 22:34:49 +00:00
BOOST_AUTO_TEST_CASE ( implicit_derived_to_base_conversion )
{
char const * text = R " (
contract A { }
contract B is A {
2017-09-05 15:11:53 +00:00
function f ( ) public { A a = B ( 1 ) ; }
2015-01-19 22:34:49 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-19 22:34:49 +00:00
}
2015-01-22 00:02:38 +00:00
2015-01-19 22:34:49 +00:00
BOOST_AUTO_TEST_CASE ( implicit_base_to_derived_conversion )
{
char const * text = R " (
contract A { }
contract B is A {
2017-09-05 15:11:53 +00:00
function f ( ) public { B b = A ( 1 ) ; }
2015-01-19 22:34:49 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Type contract A is not implicitly convertible to expected type contract B. " ) ;
2015-01-19 22:34:49 +00:00
}
2016-10-18 10:42:35 +00:00
BOOST_AUTO_TEST_CASE ( super_excludes_current_contract )
{
char const * text = R " (
contract A {
2017-09-05 15:11:53 +00:00
function b ( ) public { }
2016-10-18 10:42:35 +00:00
}
contract B is A {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-10-18 10:42:35 +00:00
super . f ( ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" f \" not found or not visible after argument-dependent lookup in contract super B " ) ;
2016-10-18 10:42:35 +00:00
}
2015-01-22 16:43:16 +00:00
BOOST_AUTO_TEST_CASE ( state_variable_accessors )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function fun ( ) public {
2016-12-03 20:52:51 +00:00
uint64 ( 2 ) ;
}
uint256 public foo ;
mapping ( uint = > bytes4 ) public map ;
mapping ( uint = > mapping ( uint = > bytes4 ) ) public multiple_map ;
}
) " ;
2015-03-24 10:11:27 +00:00
2017-08-28 18:40:38 +00:00
SourceUnit const * source ;
2015-01-23 15:37:06 +00:00
ContractDefinition const * contract ;
2017-08-28 18:40:38 +00:00
source = parseAndAnalyse ( text ) ;
2017-09-06 14:05:35 +00:00
BOOST_REQUIRE ( ( contract = retrieveContractByName ( * source , " test " ) ) ! = nullptr ) ;
2016-12-01 10:53:06 +00:00
FunctionTypePointer function = retrieveFunctionBySignature ( * contract , " foo() " ) ;
2015-01-30 15:06:56 +00:00
BOOST_REQUIRE ( function & & function - > hasDeclaration ( ) ) ;
2017-01-26 17:20:54 +00:00
auto returnParams = function - > returnParameterTypes ( ) ;
2017-06-08 09:14:58 +00:00
BOOST_CHECK_EQUAL ( returnParams . at ( 0 ) - > canonicalName ( ) , " uint256 " ) ;
2016-09-08 01:18:17 +00:00
BOOST_CHECK ( function - > stateMutability ( ) = = StateMutability : : View ) ;
2015-02-02 16:52:50 +00:00
2016-12-01 10:53:06 +00:00
function = retrieveFunctionBySignature ( * contract , " map(uint256) " ) ;
2015-01-30 15:06:56 +00:00
BOOST_REQUIRE ( function & & function - > hasDeclaration ( ) ) ;
2017-01-26 17:20:54 +00:00
auto params = function - > parameterTypes ( ) ;
2017-06-08 09:14:58 +00:00
BOOST_CHECK_EQUAL ( params . at ( 0 ) - > canonicalName ( ) , " uint256 " ) ;
2017-01-26 17:20:54 +00:00
returnParams = function - > returnParameterTypes ( ) ;
2017-06-08 09:14:58 +00:00
BOOST_CHECK_EQUAL ( returnParams . at ( 0 ) - > canonicalName ( ) , " bytes4 " ) ;
2016-09-08 01:18:17 +00:00
BOOST_CHECK ( function - > stateMutability ( ) = = StateMutability : : View ) ;
2015-02-02 16:52:50 +00:00
2016-12-01 10:53:06 +00:00
function = retrieveFunctionBySignature ( * contract , " multiple_map(uint256,uint256) " ) ;
2015-02-02 16:52:50 +00:00
BOOST_REQUIRE ( function & & function - > hasDeclaration ( ) ) ;
2017-01-26 17:20:54 +00:00
params = function - > parameterTypes ( ) ;
2017-06-08 09:14:58 +00:00
BOOST_CHECK_EQUAL ( params . at ( 0 ) - > canonicalName ( ) , " uint256 " ) ;
BOOST_CHECK_EQUAL ( params . at ( 1 ) - > canonicalName ( ) , " uint256 " ) ;
2017-01-26 17:20:54 +00:00
returnParams = function - > returnParameterTypes ( ) ;
2017-06-08 09:14:58 +00:00
BOOST_CHECK_EQUAL ( returnParams . at ( 0 ) - > canonicalName ( ) , " bytes4 " ) ;
2016-09-08 01:18:17 +00:00
BOOST_CHECK ( function - > stateMutability ( ) = = StateMutability : : View ) ;
2015-01-23 15:37:06 +00:00
}
2015-01-28 15:48:27 +00:00
BOOST_AUTO_TEST_CASE ( function_clash_with_state_variable_accessor )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function fun ( ) public {
2016-12-03 20:52:51 +00:00
uint64 ( 2 ) ;
}
uint256 foo ;
2017-09-05 15:11:53 +00:00
function foo ( ) public { }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , DeclarationError , " Identifier already declared. " ) ;
2015-01-28 15:48:27 +00:00
}
2015-01-23 15:37:06 +00:00
BOOST_AUTO_TEST_CASE ( private_state_variable )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function fun ( ) public {
2016-12-03 20:52:51 +00:00
uint64 ( 2 ) ;
}
uint256 private foo ;
uint256 internal bar ;
}
) " ;
2015-01-22 16:43:16 +00:00
ContractDefinition const * contract ;
2017-08-28 18:40:38 +00:00
SourceUnit const * source = parseAndAnalyse ( text ) ;
2017-09-06 14:05:35 +00:00
BOOST_CHECK ( ( contract = retrieveContractByName ( * source , " test " ) ) ! = nullptr ) ;
2015-02-02 16:24:09 +00:00
FunctionTypePointer function ;
2016-12-01 10:53:06 +00:00
function = retrieveFunctionBySignature ( * contract , " foo() " ) ;
2015-01-29 15:39:30 +00:00
BOOST_CHECK_MESSAGE ( function = = nullptr , " Accessor function of a private variable should not exist " ) ;
2016-12-01 10:53:06 +00:00
function = retrieveFunctionBySignature ( * contract , " bar() " ) ;
2015-02-22 18:37:54 +00:00
BOOST_CHECK_MESSAGE ( function = = nullptr , " Accessor function of an internal variable should not exist " ) ;
2015-01-22 16:43:16 +00:00
}
2016-10-22 17:05:52 +00:00
BOOST_AUTO_TEST_CASE ( missing_state_variable )
{
char const * text = R " (
contract Scope {
2017-09-05 15:11:53 +00:00
function getStateVar ( ) constant public returns ( uint stateVar ) {
2016-10-22 17:05:52 +00:00
stateVar = Scope . stateVar ; // should fail.
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" stateVar \" not found or not visible after argument-dependent lookup in type(contract Scope) " ) ;
2016-10-22 17:05:52 +00:00
}
2015-02-25 15:32:04 +00:00
BOOST_AUTO_TEST_CASE ( base_class_state_variable_accessor )
{
// test for issue #1126 https://github.com/ethereum/cpp-ethereum/issues/1126
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract Parent {
uint256 public m_aMember ;
}
contract Child is Parent {
2017-09-05 15:11:53 +00:00
function foo ( ) public returns ( uint256 ) { return Parent . m_aMember ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-02-25 15:32:04 +00:00
}
2016-01-15 16:36:06 +00:00
BOOST_AUTO_TEST_CASE ( struct_accessor_one_array_only )
{
char const * sourceCode = R " (
contract test {
2016-12-03 20:52:51 +00:00
struct Data { uint [ 15 ] m_array ; }
2016-01-15 16:36:06 +00:00
Data public data ;
}
) " ;
2017-08-24 13:08:31 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Internal or recursive type is not allowed for public state variables. " ) ;
2016-01-15 16:36:06 +00:00
}
2015-02-27 09:08:14 +00:00
BOOST_AUTO_TEST_CASE ( base_class_state_variable_internal_member )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract Parent {
uint256 internal m_aMember ;
}
2017-09-05 15:11:53 +00:00
contract Child is Parent {
function foo ( ) public returns ( uint256 ) { return Parent . m_aMember ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-02-27 09:08:14 +00:00
}
2015-02-28 17:30:33 +00:00
BOOST_AUTO_TEST_CASE ( state_variable_member_of_wrong_class1 )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract Parent1 {
uint256 internal m_aMember1 ;
}
2017-09-05 15:11:53 +00:00
contract Parent2 is Parent1 {
2016-12-03 20:52:51 +00:00
uint256 internal m_aMember2 ;
}
2017-09-05 15:11:53 +00:00
contract Child is Parent2 {
function foo ( ) public returns ( uint256 ) { return Parent2 . m_aMember1 ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" m_aMember1 \" not found or not visible after argument-dependent lookup in type(contract Parent2) " ) ;
2015-02-28 17:30:33 +00:00
}
BOOST_AUTO_TEST_CASE ( state_variable_member_of_wrong_class2 )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract Parent1 {
uint256 internal m_aMember1 ;
}
contract Parent2 is Parent1 {
uint256 internal m_aMember2 ;
}
contract Child is Parent2 {
2017-09-05 15:11:53 +00:00
function foo ( ) public returns ( uint256 ) { return Child . m_aMember2 ; }
2016-12-03 20:52:51 +00:00
uint256 public m_aMember3 ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" m_aMember2 \" not found or not visible after argument-dependent lookup in type(contract Child) " ) ;
2015-02-28 17:30:33 +00:00
}
2015-01-29 21:50:20 +00:00
BOOST_AUTO_TEST_CASE ( fallback_function )
{
char const * text = R " (
contract C {
uint x ;
2017-09-05 15:11:53 +00:00
function ( ) public { x = 2 ; }
2015-01-29 21:50:20 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-29 21:50:20 +00:00
}
BOOST_AUTO_TEST_CASE ( fallback_function_with_arguments )
{
char const * text = R " (
contract C {
uint x ;
2017-09-05 15:11:53 +00:00
function ( uint a ) public { x = 2 ; }
2015-01-29 21:50:20 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Fallback function cannot take parameters. " ) ;
2015-01-29 21:50:20 +00:00
}
2016-08-26 14:56:36 +00:00
BOOST_AUTO_TEST_CASE ( fallback_function_in_library )
{
char const * text = R " (
library C {
2017-09-05 15:11:53 +00:00
function ( ) public { }
2016-08-26 14:56:36 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Libraries cannot have fallback functions. " ) ;
2016-08-26 14:56:36 +00:00
}
2016-08-25 11:25:30 +00:00
BOOST_AUTO_TEST_CASE ( fallback_function_with_return_parameters )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function ( ) public returns ( uint ) { }
2016-08-25 11:25:30 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Fallback function cannot return values. " ) ;
2016-08-25 11:25:30 +00:00
}
2016-08-26 19:01:47 +00:00
BOOST_AUTO_TEST_CASE ( fallback_function_with_constant_modifier )
{
char const * text = R " (
contract C {
uint x ;
function ( ) constant { x = 2 ; }
}
) " ;
2017-08-15 23:28:13 +00:00
CHECK_ERROR ( text , TypeError , " Fallback function must be payable or non-payable " ) ;
2016-08-26 19:01:47 +00:00
}
2015-01-29 21:50:20 +00:00
BOOST_AUTO_TEST_CASE ( fallback_function_twice )
{
char const * text = R " (
contract C {
uint x ;
2017-09-05 15:11:53 +00:00
function ( ) public { x = 2 ; }
function ( ) public { x = 3 ; }
2015-01-29 21:50:20 +00:00
}
) " ;
2018-02-09 22:54:05 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , DeclarationError , ( vector < string > {
" Function with same name and arguments defined twice. " ,
" Only one fallback function is "
} ) ) ;
2015-01-29 21:50:20 +00:00
}
BOOST_AUTO_TEST_CASE ( fallback_function_inheritance )
{
char const * text = R " (
contract A {
uint x ;
2017-09-05 15:11:53 +00:00
function ( ) public { x = 1 ; }
2015-01-29 21:50:20 +00:00
}
contract C is A {
2017-09-05 15:11:53 +00:00
function ( ) public { x = 2 ; }
2015-01-29 21:50:20 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-29 21:50:20 +00:00
}
2015-01-29 13:35:28 +00:00
BOOST_AUTO_TEST_CASE ( event )
{
char const * text = R " (
contract c {
2015-03-09 12:49:53 +00:00
event e ( uint indexed a , bytes3 indexed s , bool indexed b ) ;
2017-09-05 15:11:53 +00:00
function f ( ) public { e ( 2 , " abc " , true ) ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-29 13:35:28 +00:00
}
BOOST_AUTO_TEST_CASE ( event_too_many_indexed )
{
char const * text = R " (
contract c {
2015-03-09 12:49:53 +00:00
event e ( uint indexed a , bytes3 indexed b , bool indexed c , uint indexed d ) ;
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " More than 3 indexed arguments for event. " ) ;
2015-01-29 13:35:28 +00:00
}
2015-10-07 14:40:54 +00:00
BOOST_AUTO_TEST_CASE ( anonymous_event_four_indexed )
{
char const * text = R " (
contract c {
event e ( uint indexed a , bytes3 indexed b , bool indexed c , uint indexed d ) anonymous ;
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-10-07 14:40:54 +00:00
}
BOOST_AUTO_TEST_CASE ( anonymous_event_too_many_indexed )
{
char const * text = R " (
contract c {
event e ( uint indexed a , bytes3 indexed b , bool indexed c , uint indexed d , uint indexed e ) anonymous ;
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " More than 4 indexed arguments for anonymous event. " ) ;
2015-10-07 14:40:54 +00:00
}
2016-10-18 12:51:49 +00:00
BOOST_AUTO_TEST_CASE ( events_with_same_name )
{
char const * text = R " (
contract TestIt {
event A ( ) ;
event A ( uint i ) ;
}
) " ;
2017-11-22 15:41:07 +00:00
CHECK_SUCCESS ( text ) ;
2016-10-18 12:51:49 +00:00
}
2017-09-29 21:45:17 +00:00
BOOST_AUTO_TEST_CASE ( events_with_same_name_unnamed_arguments )
{
char const * text = R " (
contract test {
event A ( uint ) ;
event A ( uint , uint ) ;
}
) " ;
CHECK_SUCCESS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( events_with_same_name_different_types )
{
char const * text = R " (
contract test {
event A ( uint ) ;
event A ( bytes ) ;
}
) " ;
CHECK_SUCCESS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( double_event_declaration )
{
char const * text = R " (
contract test {
event A ( uint i ) ;
event A ( uint i ) ;
}
) " ;
CHECK_ERROR ( text , DeclarationError , " Event with same name and arguments defined twice. " ) ;
}
BOOST_AUTO_TEST_CASE ( double_event_declaration_ignores_anonymous )
{
char const * text = R " (
contract test {
event A ( uint i ) ;
event A ( uint i ) anonymous ;
}
) " ;
CHECK_ERROR ( text , DeclarationError , " Event with same name and arguments defined twice. " ) ;
}
BOOST_AUTO_TEST_CASE ( double_event_declaration_ignores_indexed )
{
char const * text = R " (
contract test {
event A ( uint i ) ;
event A ( uint indexed i ) ;
}
) " ;
CHECK_ERROR ( text , DeclarationError , " Event with same name and arguments defined twice. " ) ;
}
2015-01-29 13:35:28 +00:00
BOOST_AUTO_TEST_CASE ( event_call )
{
char const * text = R " (
contract c {
2015-03-09 12:49:53 +00:00
event e ( uint a , bytes3 indexed s , bool indexed b ) ;
2017-09-05 15:11:53 +00:00
function f ( ) public { e ( 2 , " abc " , true ) ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-29 13:35:28 +00:00
}
2017-01-23 14:24:29 +00:00
BOOST_AUTO_TEST_CASE ( event_function_inheritance_clash )
{
char const * text = R " (
contract A {
2017-09-05 15:11:53 +00:00
function dup ( ) public returns ( uint ) {
2017-01-23 14:24:29 +00:00
return 1 ;
}
}
contract B {
event dup ( ) ;
}
contract C is A , B {
}
) " ;
CHECK_ERROR ( text , DeclarationError , " Identifier already declared. " ) ;
}
BOOST_AUTO_TEST_CASE ( function_event_inheritance_clash )
{
char const * text = R " (
contract B {
event dup ( ) ;
}
contract A {
2017-09-05 15:11:53 +00:00
function dup ( ) public returns ( uint ) {
2017-01-23 14:24:29 +00:00
return 1 ;
}
}
contract C is B , A {
}
) " ;
CHECK_ERROR ( text , DeclarationError , " Identifier already declared. " ) ;
}
BOOST_AUTO_TEST_CASE ( function_event_in_contract_clash )
{
char const * text = R " (
contract A {
event dup ( ) ;
2017-09-05 15:11:53 +00:00
function dup ( ) public returns ( uint ) {
2017-01-23 14:24:29 +00:00
return 1 ;
}
}
) " ;
CHECK_ERROR ( text , DeclarationError , " Identifier already declared. " ) ;
}
2015-01-29 13:35:28 +00:00
BOOST_AUTO_TEST_CASE ( event_inheritance )
{
char const * text = R " (
contract base {
2015-03-09 12:49:53 +00:00
event e ( uint a , bytes3 indexed s , bool indexed b ) ;
2015-01-29 13:35:28 +00:00
}
contract c is base {
2017-09-05 15:11:53 +00:00
function f ( ) public { e ( 2 , " abc " , true ) ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-29 13:35:28 +00:00
}
2015-01-31 15:50:33 +00:00
BOOST_AUTO_TEST_CASE ( multiple_events_argument_clash )
{
char const * text = R " (
contract c {
event e1 ( uint a , uint e1 , uint e2 ) ;
event e2 ( uint a , uint e1 , uint e2 ) ;
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-31 15:50:33 +00:00
}
2015-01-29 13:35:28 +00:00
2015-02-02 16:24:09 +00:00
BOOST_AUTO_TEST_CASE ( access_to_default_function_visibility )
{
char const * text = R " (
contract c {
2017-09-05 15:11:53 +00:00
function f ( ) public { }
2015-02-02 16:24:09 +00:00
}
contract d {
2017-09-05 15:11:53 +00:00
function g ( ) public { c ( 0 ) . f ( ) ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-02-02 16:24:09 +00:00
}
2015-02-22 18:37:54 +00:00
BOOST_AUTO_TEST_CASE ( access_to_internal_function )
2015-02-02 16:24:09 +00:00
{
char const * text = R " (
contract c {
2015-02-22 18:37:54 +00:00
function f ( ) internal { }
2015-02-02 16:24:09 +00:00
}
contract d {
2017-09-05 15:11:53 +00:00
function g ( ) public { c ( 0 ) . f ( ) ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" f \" not found or not visible after argument-dependent lookup in contract c " ) ;
2015-02-02 16:24:09 +00:00
}
BOOST_AUTO_TEST_CASE ( access_to_default_state_variable_visibility )
{
char const * text = R " (
contract c {
uint a ;
}
contract d {
2017-09-05 15:11:53 +00:00
function g ( ) public { c ( 0 ) . a ( ) ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" a \" not found or not visible after argument-dependent lookup in contract c " ) ;
2015-02-02 16:24:09 +00:00
}
2015-02-22 18:37:54 +00:00
BOOST_AUTO_TEST_CASE ( access_to_internal_state_variable )
2015-02-02 16:24:09 +00:00
{
char const * text = R " (
contract c {
uint public a ;
}
contract d {
2017-09-05 15:11:53 +00:00
function g ( ) public { c ( 0 ) . a ( ) ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-02-02 16:24:09 +00:00
}
2015-02-04 16:58:20 +00:00
BOOST_AUTO_TEST_CASE ( error_count_in_named_args )
{
2016-12-03 20:52:51 +00:00
char const * sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function a ( uint a , uint b ) public returns ( uint r ) {
2016-12-03 20:52:51 +00:00
r = a + b ;
}
2017-09-05 15:11:53 +00:00
function b ( ) public returns ( uint r ) {
2016-12-03 20:52:51 +00:00
r = a ( { a : 1 } ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Wrong argument count for function call: 1 arguments given but expected 2. " ) ;
2015-02-04 16:58:20 +00:00
}
BOOST_AUTO_TEST_CASE ( empty_in_named_args )
{
2016-12-03 20:52:51 +00:00
char const * sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function a ( uint a , uint b ) public returns ( uint r ) {
2016-12-03 20:52:51 +00:00
r = a + b ;
}
2017-09-05 15:11:53 +00:00
function b ( ) public returns ( uint r ) {
2016-12-03 20:52:51 +00:00
r = a ( { } ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Wrong argument count for function call: 0 arguments given but expected 2. " ) ;
2015-02-04 16:58:20 +00:00
}
BOOST_AUTO_TEST_CASE ( duplicate_parameter_names_in_named_args )
{
2016-12-03 20:52:51 +00:00
char const * sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function a ( uint a , uint b ) public returns ( uint r ) {
2016-12-03 20:52:51 +00:00
r = a + b ;
}
2017-09-05 15:11:53 +00:00
function b ( ) public returns ( uint r ) {
2016-12-03 20:52:51 +00:00
r = a ( { a : 1 , a : 2 } ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Duplicate named argument. " ) ;
2015-02-04 16:58:20 +00:00
}
BOOST_AUTO_TEST_CASE ( invalid_parameter_names_in_named_args )
{
2016-12-03 20:52:51 +00:00
char const * sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function a ( uint a , uint b ) public returns ( uint r ) {
2016-12-03 20:52:51 +00:00
r = a + b ;
}
2017-09-05 15:11:53 +00:00
function b ( ) public returns ( uint r ) {
2016-12-03 20:52:51 +00:00
r = a ( { a : 1 , c : 2 } ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Named argument does not match function declaration. " ) ;
2015-02-04 16:58:20 +00:00
}
2015-02-09 01:06:30 +00:00
BOOST_AUTO_TEST_CASE ( empty_name_input_parameter )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( uint ) public { }
2015-02-09 01:06:30 +00:00
}
2016-12-03 20:52:51 +00:00
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-02-09 01:06:30 +00:00
}
2017-06-15 15:36:14 +00:00
BOOST_AUTO_TEST_CASE ( constant_input_parameter )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( uint [ ] constant a ) public { }
2017-06-15 15:36:14 +00:00
}
) " ;
2018-02-09 22:54:05 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , ( vector < string > {
" Illegal use of \" constant \" specifier " ,
" Constants of non-value type not yet implemented " ,
" Uninitialized \" constant \" variable "
} ) ) ;
2017-06-15 15:36:14 +00:00
}
2015-02-09 01:06:30 +00:00
BOOST_AUTO_TEST_CASE ( empty_name_return_parameter )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( bool ) { }
2015-02-09 01:06:30 +00:00
}
2016-12-03 20:52:51 +00:00
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-02-09 01:06:30 +00:00
}
BOOST_AUTO_TEST_CASE ( empty_name_input_parameter_with_named_one )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( uint , uint k ) public returns ( uint ret_k ) {
2015-02-09 01:06:30 +00:00
return k ;
2016-12-03 20:52:51 +00:00
}
2015-02-09 01:06:30 +00:00
}
2016-12-03 20:52:51 +00:00
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-02-09 01:06:30 +00:00
}
BOOST_AUTO_TEST_CASE ( empty_name_return_parameter_with_named_one )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( uint ret_k , uint ) {
2015-02-09 01:06:30 +00:00
return 5 ;
2016-12-03 20:52:51 +00:00
}
2015-02-09 01:06:30 +00:00
}
2016-12-03 20:52:51 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Different number of arguments in return statement than in returns declaration. " ) ;
2015-02-09 01:06:30 +00:00
}
2015-02-05 23:44:38 +00:00
BOOST_AUTO_TEST_CASE ( disallow_declaration_of_void_type )
{
2016-12-03 20:52:51 +00:00
char const * sourceCode = R " (
contract c {
2017-09-05 15:11:53 +00:00
function f ( ) public { var ( x ) = f ( ) ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Not enough components (0) in value to assign all variables (1). " ) ;
2015-02-05 23:44:38 +00:00
}
2015-02-06 12:38:10 +00:00
BOOST_AUTO_TEST_CASE ( overflow_caused_by_ether_units )
{
char const * sourceCodeFine = R " (
contract c {
2017-09-05 15:11:53 +00:00
function c ( ) public {
2016-12-03 20:52:51 +00:00
a = 115792089237316195423570985008687907853269984665640564039458 ;
2015-02-06 12:38:10 +00:00
}
uint256 a ;
2016-12-03 20:52:51 +00:00
}
) " ;
2017-08-28 18:40:38 +00:00
CHECK_SUCCESS ( sourceCodeFine ) ;
2015-02-06 12:38:10 +00:00
char const * sourceCode = R " (
contract c {
2017-09-05 15:11:53 +00:00
function c ( ) public {
2015-02-06 12:38:10 +00:00
a = 115792089237316195423570985008687907853269984665640564039458 ether ;
}
uint256 a ;
2016-12-03 20:52:51 +00:00
}
) " ;
2017-12-19 15:45:04 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Type int_const 1157...(70 digits omitted)...0000 is not implicitly convertible to expected type uint256. " ) ;
2015-02-06 12:38:10 +00:00
}
2015-02-10 14:43:13 +00:00
BOOST_AUTO_TEST_CASE ( exp_operator_exponent_too_big )
2015-02-09 15:15:36 +00:00
{
char const * sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( uint d ) { return 2 * * 10000000000 ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Operator ** not compatible with types int_const 2 and int_const 10000000000 " ) ;
2015-02-09 15:15:36 +00:00
}
2015-02-12 14:19:04 +00:00
2017-03-07 12:43:51 +00:00
BOOST_AUTO_TEST_CASE ( exp_warn_literal_base )
{
char const * sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint ) {
2017-03-07 12:43:51 +00:00
uint8 x = 100 ;
return 10 * * x ;
}
}
) " ;
CHECK_WARNING ( sourceCode , " might overflow " ) ;
sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint ) {
2017-03-07 12:43:51 +00:00
uint8 x = 100 ;
return uint8 ( 10 ) * * x ;
}
}
) " ;
CHECK_SUCCESS ( sourceCode ) ;
sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint ) {
2017-03-07 12:43:51 +00:00
return 2 * * 80 ;
}
}
) " ;
CHECK_SUCCESS ( sourceCode ) ;
}
2017-08-16 11:52:06 +00:00
BOOST_AUTO_TEST_CASE ( shift_warn_literal_base )
{
char const * sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint ) {
2017-08-16 11:52:06 +00:00
uint8 x = 100 ;
return 10 < < x ;
}
}
) " ;
CHECK_WARNING ( sourceCode , " might overflow " ) ;
sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint ) {
2017-08-16 11:52:06 +00:00
uint8 x = 100 ;
return uint8 ( 10 ) < < x ;
}
}
) " ;
CHECK_SUCCESS ( sourceCode ) ;
sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint ) {
2017-08-16 11:52:06 +00:00
return 2 < < 80 ;
}
}
) " ;
CHECK_SUCCESS ( sourceCode ) ;
sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint ) {
2017-08-16 11:52:06 +00:00
uint8 x = 100 ;
return 10 > > x ;
}
}
) " ;
CHECK_SUCCESS ( sourceCode ) ;
}
2017-06-22 13:22:49 +00:00
BOOST_AUTO_TEST_CASE ( warn_var_from_zero )
{
char const * sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint ) {
2017-06-22 13:22:49 +00:00
var i = 1 ;
return i ;
}
}
) " ;
2018-02-12 22:26:13 +00:00
CHECK_WARNING_ALLOW_MULTI ( sourceCode , ( std : : vector < std : : string > {
" uint8, which can hold values between 0 and 255 " ,
" Use of the \" var \" keyword is deprecated. "
} ) ) ;
2017-06-26 07:49:45 +00:00
sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-06-26 07:49:45 +00:00
var i = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ;
i ;
}
}
) " ;
2018-02-12 22:26:13 +00:00
CHECK_WARNING_ALLOW_MULTI ( sourceCode , ( std : : vector < std : : string > {
" uint256, which can hold values between 0 and 115792089237316195423570985008687907853269984665640564039457584007913129639935 " ,
" Use of the \" var \" keyword is deprecated. "
} ) ) ;
2017-06-26 07:49:45 +00:00
sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-06-26 07:49:45 +00:00
var i = - 2 ;
i ;
}
}
) " ;
2018-02-12 22:26:13 +00:00
CHECK_WARNING_ALLOW_MULTI ( sourceCode , ( std : : vector < std : : string > {
" int8, which can hold values between -128 and 127 " ,
" Use of the \" var \" keyword is deprecated. "
} ) ) ;
2017-06-22 13:22:49 +00:00
sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-06-22 13:22:49 +00:00
for ( var i = 0 ; i < msg . data . length ; i + + ) { }
}
}
2017-06-26 07:49:45 +00:00
) " ;
2018-02-12 22:26:13 +00:00
CHECK_WARNING_ALLOW_MULTI ( sourceCode , ( std : : vector < std : : string > {
" uint8, which can hold " ,
" Use of the \" var \" keyword is deprecated. "
} ) ) ;
2017-06-22 13:22:49 +00:00
}
2015-02-11 20:40:47 +00:00
BOOST_AUTO_TEST_CASE ( enum_member_access )
{
char const * text = R " (
2016-12-03 20:52:51 +00:00
contract test {
enum ActionChoices { GoLeft , GoRight , GoStraight , Sit }
function test ( )
{
choices = ActionChoices . GoStraight ;
2015-02-11 20:40:47 +00:00
}
2016-12-03 20:52:51 +00:00
ActionChoices choices ;
}
2015-02-11 20:40:47 +00:00
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-02-11 20:40:47 +00:00
}
2015-02-09 15:15:36 +00:00
2015-12-18 14:56:26 +00:00
BOOST_AUTO_TEST_CASE ( enum_member_access_accross_contracts )
{
char const * text = R " (
2016-12-03 20:52:51 +00:00
contract Interface {
enum MyEnum { One , Two }
}
contract Impl {
2017-09-05 15:11:53 +00:00
function test ( ) public returns ( Interface . MyEnum ) {
2016-12-03 20:52:51 +00:00
return Interface . MyEnum . One ;
2015-12-18 14:56:26 +00:00
}
2016-12-03 20:52:51 +00:00
}
2015-12-18 14:56:26 +00:00
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-12-18 14:56:26 +00:00
}
2015-02-12 14:19:04 +00:00
BOOST_AUTO_TEST_CASE ( enum_invalid_member_access )
{
char const * text = R " (
2016-12-03 20:52:51 +00:00
contract test {
enum ActionChoices { GoLeft , GoRight , GoStraight , Sit }
2017-09-05 15:11:53 +00:00
function test ( ) public {
2016-12-03 20:52:51 +00:00
choices = ActionChoices . RunAroundWavingYourHands ;
2015-02-12 14:19:04 +00:00
}
2016-12-03 20:52:51 +00:00
ActionChoices choices ;
}
2015-02-12 14:19:04 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" RunAroundWavingYourHands \" not found or not visible after argument-dependent lookup in type(enum test.ActionChoices) " ) ;
2015-02-12 14:19:04 +00:00
}
2016-10-21 10:17:09 +00:00
BOOST_AUTO_TEST_CASE ( enum_invalid_direct_member_access )
{
char const * text = R " (
2016-12-03 20:52:51 +00:00
contract test {
enum ActionChoices { GoLeft , GoRight , GoStraight , Sit }
2017-09-05 15:11:53 +00:00
function test ( ) public {
2016-12-03 20:52:51 +00:00
choices = Sit ;
2016-10-21 10:17:09 +00:00
}
2016-12-03 20:52:51 +00:00
ActionChoices choices ;
}
2016-10-21 10:17:09 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , DeclarationError , " Undeclared identifier. " ) ;
2016-10-21 10:17:09 +00:00
}
2015-02-12 16:59:52 +00:00
BOOST_AUTO_TEST_CASE ( enum_explicit_conversion_is_okay )
{
char const * text = R " (
2016-12-03 20:52:51 +00:00
contract test {
enum ActionChoices { GoLeft , GoRight , GoStraight , Sit }
2017-09-05 15:11:53 +00:00
function test ( ) public {
2016-12-03 20:52:51 +00:00
a = uint256 ( ActionChoices . GoStraight ) ;
b = uint64 ( ActionChoices . Sit ) ;
2015-02-12 16:59:52 +00:00
}
2016-12-03 20:52:51 +00:00
uint256 a ;
uint64 b ;
}
2015-02-12 16:59:52 +00:00
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-02-12 16:59:52 +00:00
}
2015-02-13 22:14:58 +00:00
BOOST_AUTO_TEST_CASE ( int_to_enum_explicit_conversion_is_okay )
{
char const * text = R " (
2016-12-03 20:52:51 +00:00
contract test {
enum ActionChoices { GoLeft , GoRight , GoStraight , Sit }
2017-09-05 15:11:53 +00:00
function test ( ) public {
2016-12-03 20:52:51 +00:00
a = 2 ;
b = ActionChoices ( a ) ;
2015-02-13 22:14:58 +00:00
}
2016-12-03 20:52:51 +00:00
uint256 a ;
ActionChoices b ;
}
2015-02-13 22:14:58 +00:00
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-02-13 22:14:58 +00:00
}
2016-12-05 14:40:35 +00:00
BOOST_AUTO_TEST_CASE ( enum_implicit_conversion_is_not_okay_256 )
2015-02-12 16:59:52 +00:00
{
char const * text = R " (
2016-12-03 20:52:51 +00:00
contract test {
enum ActionChoices { GoLeft , GoRight , GoStraight , Sit }
2017-09-05 15:11:53 +00:00
function test ( ) public {
2016-12-03 20:52:51 +00:00
a = ActionChoices . GoStraight ;
2015-02-12 16:59:52 +00:00
}
2016-12-03 20:52:51 +00:00
uint256 a ;
2016-12-05 14:40:35 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Type enum test.ActionChoices is not implicitly convertible to expected type uint256. " ) ;
2016-12-05 14:40:35 +00:00
}
BOOST_AUTO_TEST_CASE ( enum_implicit_conversion_is_not_okay_64 )
{
char const * text = R " (
contract test {
enum ActionChoices { GoLeft , GoRight , GoStraight , Sit }
2017-09-05 15:11:53 +00:00
function test ( ) public {
2016-12-05 14:40:35 +00:00
b = ActionChoices . Sit ;
}
2016-12-03 20:52:51 +00:00
uint64 b ;
}
2015-02-12 16:59:52 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Type enum test.ActionChoices is not implicitly convertible to expected type uint64. " ) ;
2015-02-12 16:59:52 +00:00
}
2016-11-09 14:53:00 +00:00
BOOST_AUTO_TEST_CASE ( enum_to_enum_conversion_is_not_okay )
{
char const * text = R " (
contract test {
enum Paper { Up , Down , Left , Right }
enum Ground { North , South , West , East }
2017-09-05 15:11:53 +00:00
function test ( ) public {
2016-11-09 14:53:00 +00:00
Ground ( Paper . Up ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Explicit type conversion not allowed from \" enum test.Paper \" to \" enum test.Ground \" . " ) ;
2016-11-09 14:53:00 +00:00
}
2015-02-13 12:32:18 +00:00
BOOST_AUTO_TEST_CASE ( enum_duplicate_values )
{
char const * text = R " (
contract test {
2015-02-13 22:47:55 +00:00
enum ActionChoices { GoLeft , GoRight , GoLeft , Sit }
2015-02-13 12:32:18 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , DeclarationError , " Identifier already declared. " ) ;
2015-02-13 12:32:18 +00:00
}
2016-10-18 11:02:43 +00:00
BOOST_AUTO_TEST_CASE ( enum_name_resolution_under_current_contract_name )
{
char const * text = R " (
contract A {
enum Foo {
First ,
Second
}
2017-09-05 15:11:53 +00:00
function a ( ) public {
2016-10-18 11:02:43 +00:00
A . Foo ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-10-18 11:02:43 +00:00
}
2015-02-13 23:43:02 +00:00
BOOST_AUTO_TEST_CASE ( private_visibility )
{
char const * sourceCode = R " (
contract base {
function f ( ) private { }
}
contract derived is base {
2017-09-05 15:11:53 +00:00
function g ( ) public { f ( ) ; }
2015-02-13 23:43:02 +00:00
}
2016-12-03 20:52:51 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , DeclarationError , " Undeclared identifier. " ) ;
2015-02-13 23:43:02 +00:00
}
BOOST_AUTO_TEST_CASE ( private_visibility_via_explicit_base_access )
{
char const * sourceCode = R " (
contract base {
function f ( ) private { }
}
contract derived is base {
2017-09-05 15:11:53 +00:00
function g ( ) public { base . f ( ) ; }
2015-02-13 23:43:02 +00:00
}
2016-12-03 20:52:51 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Member \" f \" not found or not visible after argument-dependent lookup in type(contract base) " ) ;
2015-02-13 23:43:02 +00:00
}
BOOST_AUTO_TEST_CASE ( external_visibility )
{
char const * sourceCode = R " (
contract c {
function f ( ) external { }
2017-09-05 15:11:53 +00:00
function g ( ) public { f ( ) ; }
2015-02-13 23:43:02 +00:00
}
2016-12-03 20:52:51 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , DeclarationError , " Undeclared identifier. " ) ;
2015-02-13 23:43:02 +00:00
}
2017-10-29 08:08:40 +00:00
BOOST_AUTO_TEST_CASE ( similar_name_suggestions_expected )
{
char const * sourceCode = R " (
contract c {
function func ( ) { }
function g ( ) public { fun ( ) ; }
}
) " ;
2017-11-17 16:11:15 +00:00
CHECK_ERROR ( sourceCode , DeclarationError , " Undeclared identifier. Did you mean \" func \" ? " ) ;
2017-10-29 08:08:40 +00:00
}
BOOST_AUTO_TEST_CASE ( no_name_suggestion )
{
char const * sourceCode = R " (
contract c {
function g ( ) public { fun ( ) ; }
}
) " ;
CHECK_ERROR ( sourceCode , DeclarationError , " Undeclared identifier. " ) ;
}
BOOST_AUTO_TEST_CASE ( multiple_similar_suggestions )
{
char const * sourceCode = R " (
contract c {
function g ( ) public {
uint var1 = 1 ;
uint var2 = 1 ;
uint var3 = 1 ;
uint var4 = 1 ;
uint var5 = varx ;
}
}
) " ;
2017-11-17 16:11:15 +00:00
CHECK_ERROR ( sourceCode , DeclarationError , " Undeclared identifier. Did you mean \" var1 \" , \" var2 \" , \" var3 \" , \" var4 \" or \" var5 \" ? " ) ;
2017-10-29 08:08:40 +00:00
}
BOOST_AUTO_TEST_CASE ( multiple_scopes_suggestions )
{
char const * sourceCode = R " (
contract c {
uint log9 = 2 ;
function g ( ) public {
uint log8 = 3 ;
uint var1 = lgox ;
}
}
) " ;
2017-11-17 16:11:15 +00:00
CHECK_ERROR ( sourceCode , DeclarationError , " Undeclared identifier. Did you mean \" log8 \" , \" log9 \" , \" log0 \" , \" log1 \" , \" log2 \" , \" log3 \" or \" log4 \" ? " ) ;
2017-10-29 08:08:40 +00:00
}
BOOST_AUTO_TEST_CASE ( inheritence_suggestions )
{
char const * sourceCode = R " (
contract a { function func ( ) public { } }
contract c is a {
function g ( ) public {
uint var1 = fun ( ) ;
}
}
) " ;
2017-11-17 16:11:15 +00:00
CHECK_ERROR ( sourceCode , DeclarationError , " Undeclared identifier. Did you mean \" func \" ? " ) ;
2017-10-29 08:08:40 +00:00
}
BOOST_AUTO_TEST_CASE ( no_spurious_suggestions )
{
char const * sourceCode = R " (
contract c {
function g ( ) public {
uint va = 1 ;
uint vb = vaxyz ;
}
}
) " ;
CHECK_ERROR ( sourceCode , DeclarationError , " Undeclared identifier. " ) ;
sourceCode = R " (
contract c {
function g ( ) public {
uint va = 1 ;
uint vb = x ;
}
}
) " ;
CHECK_ERROR ( sourceCode , DeclarationError , " Undeclared identifier. " ) ;
}
2015-02-13 23:43:02 +00:00
BOOST_AUTO_TEST_CASE ( external_base_visibility )
{
char const * sourceCode = R " (
contract base {
function f ( ) external { }
}
contract derived is base {
2017-09-05 15:11:53 +00:00
function g ( ) public { base . f ( ) ; }
2015-02-13 23:43:02 +00:00
}
2016-12-03 20:52:51 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Member \" f \" not found or not visible after argument-dependent lookup in type(contract base) " ) ;
2015-02-13 23:43:02 +00:00
}
2015-02-14 00:22:44 +00:00
BOOST_AUTO_TEST_CASE ( external_argument_assign )
{
char const * sourceCode = R " (
contract c {
function f ( uint a ) external { a = 1 ; }
}
2016-12-03 20:52:51 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Expression has to be an lvalue. " ) ;
2015-02-14 00:22:44 +00:00
}
BOOST_AUTO_TEST_CASE ( external_argument_increment )
{
char const * sourceCode = R " (
contract c {
function f ( uint a ) external { a + + ; }
}
2016-12-03 20:52:51 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Expression has to be an lvalue. " ) ;
2015-02-14 00:22:44 +00:00
}
BOOST_AUTO_TEST_CASE ( external_argument_delete )
{
char const * sourceCode = R " (
contract c {
function f ( uint a ) external { delete a ; }
}
2016-12-03 20:52:51 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Expression has to be an lvalue. " ) ;
2015-02-14 00:22:44 +00:00
}
2015-02-19 16:43:53 +00:00
BOOST_AUTO_TEST_CASE ( test_for_bug_override_function_with_bytearray_type )
{
char const * sourceCode = R " (
contract Vehicle {
2017-04-14 14:48:59 +00:00
function f ( bytes ) external returns ( uint256 r ) { r = 1 ; }
2015-02-19 16:43:53 +00:00
}
contract Bike is Vehicle {
2017-04-14 14:48:59 +00:00
function f ( bytes ) external returns ( uint256 r ) { r = 42 ; }
2015-02-19 16:43:53 +00:00
}
2016-12-03 20:52:51 +00:00
) " ;
2017-08-28 18:40:38 +00:00
CHECK_SUCCESS ( sourceCode ) ;
2015-02-19 16:43:53 +00:00
}
2015-02-20 14:52:30 +00:00
BOOST_AUTO_TEST_CASE ( array_with_nonconstant_length )
{
char const * text = R " (
contract c {
2017-09-05 15:11:53 +00:00
function f ( uint a ) public { uint8 [ a ] x ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-11-22 12:33:11 +00:00
CHECK_ERROR ( text , TypeError , " Invalid array length, expected integer literal or constant expression. " ) ;
2015-02-20 14:52:30 +00:00
}
2017-02-02 00:24:45 +00:00
BOOST_AUTO_TEST_CASE ( array_with_negative_length )
{
char const * text = R " (
contract c {
2017-09-05 15:11:53 +00:00
function f ( uint a ) public { uint8 [ - 1 ] x ; }
2017-02-02 00:24:45 +00:00
}
) " ;
CHECK_ERROR ( text , TypeError , " Array with negative length specified " ) ;
}
2015-02-27 13:50:06 +00:00
BOOST_AUTO_TEST_CASE ( array_copy_with_different_types1 )
{
char const * text = R " (
contract c {
bytes a ;
uint [ ] b ;
2017-09-05 15:11:53 +00:00
function f ( ) public { b = a ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Type bytes storage ref is not implicitly convertible to expected type uint256[] storage ref. " ) ;
2015-02-27 13:50:06 +00:00
}
BOOST_AUTO_TEST_CASE ( array_copy_with_different_types2 )
{
char const * text = R " (
contract c {
uint32 [ ] a ;
uint8 [ ] b ;
2017-09-05 15:11:53 +00:00
function f ( ) public { b = a ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Type uint32[] storage ref is not implicitly convertible to expected type uint8[] storage ref. " ) ;
2015-02-27 13:50:06 +00:00
}
BOOST_AUTO_TEST_CASE ( array_copy_with_different_types_conversion_possible )
{
char const * text = R " (
contract c {
uint32 [ ] a ;
uint8 [ ] b ;
2017-09-05 15:11:53 +00:00
function f ( ) public { a = b ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-02-27 13:50:06 +00:00
}
BOOST_AUTO_TEST_CASE ( array_copy_with_different_types_static_dynamic )
{
char const * text = R " (
contract c {
uint32 [ ] a ;
uint8 [ 80 ] b ;
2017-09-05 15:11:53 +00:00
function f ( ) public { a = b ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-02-27 13:50:06 +00:00
}
BOOST_AUTO_TEST_CASE ( array_copy_with_different_types_dynamic_static )
{
char const * text = R " (
contract c {
uint [ ] a ;
uint [ 80 ] b ;
2017-09-05 15:11:53 +00:00
function f ( ) public { b = a ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Type uint256[] storage ref is not implicitly convertible to expected type uint256[80] storage ref. " ) ;
2015-02-27 13:50:06 +00:00
}
2018-02-11 22:44:23 +00:00
BOOST_AUTO_TEST_CASE ( array_of_undeclared_type )
{
char const * text = R " (
contract c {
a [ ] public foo ;
}
) " ;
CHECK_ERROR ( text , DeclarationError , " Identifier not found or not unique. " ) ;
}
2015-03-06 12:44:37 +00:00
BOOST_AUTO_TEST_CASE ( storage_variable_initialization_with_incorrect_type_int )
{
char const * text = R " (
contract c {
uint8 a = 1000 ;
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Type int_const 1000 is not implicitly convertible to expected type uint8. " ) ;
2015-03-06 12:44:37 +00:00
}
BOOST_AUTO_TEST_CASE ( storage_variable_initialization_with_incorrect_type_string )
{
char const * text = R " (
contract c {
uint a = " abc " ;
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Type literal_string \" abc \" is not implicitly convertible to expected type uint256. " ) ;
2015-03-06 12:44:37 +00:00
}
2015-03-09 16:48:33 +00:00
BOOST_AUTO_TEST_CASE ( test_fromElementaryTypeName )
{
2016-02-08 21:43:22 +00:00
2016-02-12 21:01:27 +00:00
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : Int , 0 , 0 ) ) = = * make_shared < IntegerType > ( 256 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 8 , 0 ) ) = = * make_shared < IntegerType > ( 8 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 16 , 0 ) ) = = * make_shared < IntegerType > ( 16 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 24 , 0 ) ) = = * make_shared < IntegerType > ( 24 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 32 , 0 ) ) = = * make_shared < IntegerType > ( 32 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 40 , 0 ) ) = = * make_shared < IntegerType > ( 40 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 48 , 0 ) ) = = * make_shared < IntegerType > ( 48 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 56 , 0 ) ) = = * make_shared < IntegerType > ( 56 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 64 , 0 ) ) = = * make_shared < IntegerType > ( 64 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 72 , 0 ) ) = = * make_shared < IntegerType > ( 72 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 80 , 0 ) ) = = * make_shared < IntegerType > ( 80 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 88 , 0 ) ) = = * make_shared < IntegerType > ( 88 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 96 , 0 ) ) = = * make_shared < IntegerType > ( 96 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 104 , 0 ) ) = = * make_shared < IntegerType > ( 104 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 112 , 0 ) ) = = * make_shared < IntegerType > ( 112 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 120 , 0 ) ) = = * make_shared < IntegerType > ( 120 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 128 , 0 ) ) = = * make_shared < IntegerType > ( 128 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 136 , 0 ) ) = = * make_shared < IntegerType > ( 136 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 144 , 0 ) ) = = * make_shared < IntegerType > ( 144 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 152 , 0 ) ) = = * make_shared < IntegerType > ( 152 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 160 , 0 ) ) = = * make_shared < IntegerType > ( 160 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 168 , 0 ) ) = = * make_shared < IntegerType > ( 168 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 176 , 0 ) ) = = * make_shared < IntegerType > ( 176 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 184 , 0 ) ) = = * make_shared < IntegerType > ( 184 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 192 , 0 ) ) = = * make_shared < IntegerType > ( 192 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 200 , 0 ) ) = = * make_shared < IntegerType > ( 200 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 208 , 0 ) ) = = * make_shared < IntegerType > ( 208 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 216 , 0 ) ) = = * make_shared < IntegerType > ( 216 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 224 , 0 ) ) = = * make_shared < IntegerType > ( 224 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 232 , 0 ) ) = = * make_shared < IntegerType > ( 232 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 240 , 0 ) ) = = * make_shared < IntegerType > ( 240 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 248 , 0 ) ) = = * make_shared < IntegerType > ( 248 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : IntM , 256 , 0 ) ) = = * make_shared < IntegerType > ( 256 , IntegerType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UInt , 0 , 0 ) ) = = * make_shared < IntegerType > ( 256 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 8 , 0 ) ) = = * make_shared < IntegerType > ( 8 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 16 , 0 ) ) = = * make_shared < IntegerType > ( 16 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 24 , 0 ) ) = = * make_shared < IntegerType > ( 24 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 32 , 0 ) ) = = * make_shared < IntegerType > ( 32 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 40 , 0 ) ) = = * make_shared < IntegerType > ( 40 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 48 , 0 ) ) = = * make_shared < IntegerType > ( 48 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 56 , 0 ) ) = = * make_shared < IntegerType > ( 56 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 64 , 0 ) ) = = * make_shared < IntegerType > ( 64 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 72 , 0 ) ) = = * make_shared < IntegerType > ( 72 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 80 , 0 ) ) = = * make_shared < IntegerType > ( 80 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 88 , 0 ) ) = = * make_shared < IntegerType > ( 88 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 96 , 0 ) ) = = * make_shared < IntegerType > ( 96 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 104 , 0 ) ) = = * make_shared < IntegerType > ( 104 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 112 , 0 ) ) = = * make_shared < IntegerType > ( 112 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 120 , 0 ) ) = = * make_shared < IntegerType > ( 120 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 128 , 0 ) ) = = * make_shared < IntegerType > ( 128 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 136 , 0 ) ) = = * make_shared < IntegerType > ( 136 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 144 , 0 ) ) = = * make_shared < IntegerType > ( 144 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 152 , 0 ) ) = = * make_shared < IntegerType > ( 152 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 160 , 0 ) ) = = * make_shared < IntegerType > ( 160 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 168 , 0 ) ) = = * make_shared < IntegerType > ( 168 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 176 , 0 ) ) = = * make_shared < IntegerType > ( 176 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 184 , 0 ) ) = = * make_shared < IntegerType > ( 184 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 192 , 0 ) ) = = * make_shared < IntegerType > ( 192 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 200 , 0 ) ) = = * make_shared < IntegerType > ( 200 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 208 , 0 ) ) = = * make_shared < IntegerType > ( 208 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 216 , 0 ) ) = = * make_shared < IntegerType > ( 216 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 224 , 0 ) ) = = * make_shared < IntegerType > ( 224 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 232 , 0 ) ) = = * make_shared < IntegerType > ( 232 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 240 , 0 ) ) = = * make_shared < IntegerType > ( 240 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 248 , 0 ) ) = = * make_shared < IntegerType > ( 248 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UIntM , 256 , 0 ) ) = = * make_shared < IntegerType > ( 256 , IntegerType : : Modifier : : Unsigned ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : Byte , 0 , 0 ) ) = = * make_shared < FixedBytesType > ( 1 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 1 , 0 ) ) = = * make_shared < FixedBytesType > ( 1 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 2 , 0 ) ) = = * make_shared < FixedBytesType > ( 2 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 3 , 0 ) ) = = * make_shared < FixedBytesType > ( 3 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 4 , 0 ) ) = = * make_shared < FixedBytesType > ( 4 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 5 , 0 ) ) = = * make_shared < FixedBytesType > ( 5 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 6 , 0 ) ) = = * make_shared < FixedBytesType > ( 6 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 7 , 0 ) ) = = * make_shared < FixedBytesType > ( 7 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 8 , 0 ) ) = = * make_shared < FixedBytesType > ( 8 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 9 , 0 ) ) = = * make_shared < FixedBytesType > ( 9 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 10 , 0 ) ) = = * make_shared < FixedBytesType > ( 10 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 11 , 0 ) ) = = * make_shared < FixedBytesType > ( 11 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 12 , 0 ) ) = = * make_shared < FixedBytesType > ( 12 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 13 , 0 ) ) = = * make_shared < FixedBytesType > ( 13 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 14 , 0 ) ) = = * make_shared < FixedBytesType > ( 14 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 15 , 0 ) ) = = * make_shared < FixedBytesType > ( 15 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 16 , 0 ) ) = = * make_shared < FixedBytesType > ( 16 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 17 , 0 ) ) = = * make_shared < FixedBytesType > ( 17 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 18 , 0 ) ) = = * make_shared < FixedBytesType > ( 18 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 19 , 0 ) ) = = * make_shared < FixedBytesType > ( 19 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 20 , 0 ) ) = = * make_shared < FixedBytesType > ( 20 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 21 , 0 ) ) = = * make_shared < FixedBytesType > ( 21 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 22 , 0 ) ) = = * make_shared < FixedBytesType > ( 22 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 23 , 0 ) ) = = * make_shared < FixedBytesType > ( 23 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 24 , 0 ) ) = = * make_shared < FixedBytesType > ( 24 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 25 , 0 ) ) = = * make_shared < FixedBytesType > ( 25 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 26 , 0 ) ) = = * make_shared < FixedBytesType > ( 26 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 27 , 0 ) ) = = * make_shared < FixedBytesType > ( 27 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 28 , 0 ) ) = = * make_shared < FixedBytesType > ( 28 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 29 , 0 ) ) = = * make_shared < FixedBytesType > ( 29 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 30 , 0 ) ) = = * make_shared < FixedBytesType > ( 30 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 31 , 0 ) ) = = * make_shared < FixedBytesType > ( 31 ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : BytesM , 32 , 0 ) ) = = * make_shared < FixedBytesType > ( 32 ) ) ;
2017-07-12 13:44:27 +00:00
2018-02-16 15:11:07 +00:00
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : Fixed , 0 , 0 ) ) = = * make_shared < FixedPointType > ( 128 , 18 , FixedPointType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UFixed , 0 , 0 ) ) = = * make_shared < FixedPointType > ( 128 , 18 , FixedPointType : : Modifier : : Unsigned ) ) ;
2015-03-09 16:48:33 +00:00
}
2015-03-11 16:41:12 +00:00
BOOST_AUTO_TEST_CASE ( test_byte_is_alias_of_byte1 )
{
char const * text = R " (
contract c {
bytes arr ;
2017-09-05 15:11:53 +00:00
function f ( ) public { byte a = arr [ 0 ] ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-08-28 18:40:38 +00:00
CHECK_SUCCESS ( text ) ;
2015-03-11 16:41:12 +00:00
}
2017-06-22 14:14:14 +00:00
BOOST_AUTO_TEST_CASE ( warns_assigning_decimal_to_bytesxx )
{
char const * text = R " (
contract Foo {
bytes32 a = 7 ;
}
) " ;
CHECK_WARNING ( text , " Decimal literal assigned to bytesXX variable will be left-aligned. " ) ;
}
BOOST_AUTO_TEST_CASE ( does_not_warn_assigning_hex_number_to_bytesxx )
{
char const * text = R " (
contract Foo {
bytes32 a = 0x1234 ;
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( explicit_conversion_from_decimal_to_bytesxx )
{
char const * text = R " (
contract Foo {
bytes32 a = bytes32 ( 7 ) ;
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2018-03-01 15:58:20 +00:00
BOOST_AUTO_TEST_CASE ( combining_hex_and_denomination )
{
char const * text = R " (
contract Foo {
uint constant x = 0x01 wei ;
}
) " ;
CHECK_WARNING ( text , " Hexadecimal numbers with unit denominations are deprecated. " ) ;
char const * textV050 = R " (
pragma experimental " v0.5.0 " ;
contract Foo {
uint constant x = 0x01 wei ;
}
) " ;
CHECK_ERROR ( textV050 , TypeError , " Hexadecimal numbers cannot be used with unit denominations. " ) ;
}
2015-03-13 17:16:04 +00:00
BOOST_AUTO_TEST_CASE ( assigning_value_to_const_variable )
2015-03-03 11:58:01 +00:00
{
char const * text = R " (
contract Foo {
2017-09-05 15:11:53 +00:00
function changeIt ( ) public { x = 9 ; }
2015-03-12 13:15:04 +00:00
uint constant x = 56 ;
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Cannot assign to a constant variable. " ) ;
2015-03-03 11:58:01 +00:00
}
2017-07-08 23:27:28 +00:00
BOOST_AUTO_TEST_CASE ( assigning_state_to_const_variable_0_4_x )
2017-03-01 15:34:29 +00:00
{
char const * text = R " (
contract C {
address constant x = msg . sender ;
}
) " ;
2017-03-14 18:25:16 +00:00
CHECK_WARNING ( text , " Initial value for constant variable has to be compile-time constant. " ) ;
2017-03-01 18:12:40 +00:00
}
2017-07-08 23:27:28 +00:00
BOOST_AUTO_TEST_CASE ( assigning_state_to_const_variable )
{
char const * text = R " (
pragma experimental " v0.5.0 " ;
contract C {
address constant x = msg . sender ;
}
) " ;
CHECK_ERROR ( text , TypeError , " Initial value for constant variable has to be compile-time constant. " ) ;
}
2017-03-03 18:26:54 +00:00
BOOST_AUTO_TEST_CASE ( constant_string_literal_disallows_assignment )
{
char const * text = R " (
contract Test {
string constant x = " abefghijklmnopqabcdefghijklmnopqabcdefghijklmnopqabca " ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-03-03 18:26:54 +00:00
x [ 0 ] = " f " ;
}
}
) " ;
// Even if this is made possible in the future, we should not allow assignment
// to elements of constant arrays.
CHECK_ERROR ( text , TypeError , " Index access for string is not possible. " ) ;
}
2017-07-08 23:27:28 +00:00
BOOST_AUTO_TEST_CASE ( assign_constant_function_value_to_constant_0_4_x )
2017-03-01 18:12:40 +00:00
{
char const * text = R " (
contract C {
function ( ) constant returns ( uint ) x ;
uint constant y = x ( ) ;
}
) " ;
2017-03-14 18:25:16 +00:00
CHECK_WARNING ( text , " Initial value for constant variable has to be compile-time constant. " ) ;
2017-03-01 15:34:29 +00:00
}
2017-07-08 23:27:28 +00:00
BOOST_AUTO_TEST_CASE ( assign_constant_function_value_to_constant )
{
char const * text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function ( ) constant returns ( uint ) x ;
uint constant y = x ( ) ;
}
) " ;
CHECK_ERROR ( text , TypeError , " Initial value for constant variable has to be compile-time constant. " ) ;
}
2017-03-01 15:34:29 +00:00
BOOST_AUTO_TEST_CASE ( assignment_to_const_var_involving_conversion )
{
char const * text = R " (
contract C {
C constant x = C ( 0x123 ) ;
}
) " ;
CHECK_SUCCESS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( assignment_to_const_var_involving_expression )
{
char const * text = R " (
contract C {
2017-03-01 18:12:40 +00:00
uint constant x = 0x123 + 0x456 ;
2017-03-01 15:34:29 +00:00
}
) " ;
CHECK_SUCCESS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( assignment_to_const_var_involving_keccak )
{
char const * text = R " (
contract C {
2017-03-01 18:12:40 +00:00
bytes32 constant x = keccak256 ( " abc " ) ;
2017-03-01 15:34:29 +00:00
}
) " ;
CHECK_SUCCESS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( assignment_to_const_array_vars )
{
char const * text = R " (
contract C {
2017-03-01 18:12:40 +00:00
uint [ 3 ] constant x = [ uint ( 1 ) , 2 , 3 ] ;
2017-03-01 15:34:29 +00:00
}
) " ;
2017-03-03 18:26:54 +00:00
CHECK_ERROR ( text , TypeError , " implemented " ) ;
2017-03-01 15:34:29 +00:00
}
2017-09-18 21:25:50 +00:00
BOOST_AUTO_TEST_CASE ( assignment_to_const_string_bytes )
{
char const * text = R " (
contract C {
bytes constant a = " \x00 \x01 \x02 " ;
bytes constant b = hex " 000102 " ;
string constant c = " hello " ;
}
) " ;
CHECK_SUCCESS ( text ) ;
}
2017-03-01 18:12:40 +00:00
BOOST_AUTO_TEST_CASE ( constant_struct )
2015-03-13 17:16:04 +00:00
{
char const * text = R " (
2017-03-01 18:12:40 +00:00
contract C {
struct S { uint x ; uint [ ] y ; }
S constant x = S ( 5 , new uint [ ] ( 4 ) ) ;
2016-12-03 20:52:51 +00:00
}
) " ;
2017-03-03 18:26:54 +00:00
CHECK_ERROR ( text , TypeError , " implemented " ) ;
2015-03-13 17:16:04 +00:00
}
2017-06-23 09:19:37 +00:00
BOOST_AUTO_TEST_CASE ( address_is_constant )
{
char const * text = R " (
contract C {
address constant x = 0x1212121212121212121212121212121212121212 ;
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2015-03-13 17:16:04 +00:00
BOOST_AUTO_TEST_CASE ( uninitialized_const_variable )
{
char const * text = R " (
contract Foo {
uint constant y ;
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Uninitialized \" constant \" variable. " ) ;
2015-03-13 17:16:04 +00:00
}
2015-03-01 03:33:38 +00:00
BOOST_AUTO_TEST_CASE ( overloaded_function_cannot_resolve )
{
char const * sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( uint ) { return 1 ; }
function f ( uint a ) public returns ( uint ) { return a ; }
function g ( ) public returns ( uint ) { return f ( 3 , 5 ) ; }
2015-03-01 03:33:38 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " No matching declaration found after argument-dependent lookup. " ) ;
2015-03-01 03:33:38 +00:00
}
BOOST_AUTO_TEST_CASE ( ambiguous_overloaded_function )
{
2015-04-15 15:40:50 +00:00
// literal 1 can be both converted to uint and uint8, so the call is ambiguous.
2015-03-01 03:33:38 +00:00
char const * sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( uint8 a ) public returns ( uint ) { return a ; }
function f ( uint a ) public returns ( uint ) { return 2 * a ; }
function g ( ) public returns ( uint ) { return f ( 1 ) ; }
2015-03-01 03:33:38 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " No unique declaration found after argument-dependent lookup. " ) ;
2015-03-01 03:33:38 +00:00
}
2015-04-15 15:40:50 +00:00
BOOST_AUTO_TEST_CASE ( assignment_of_nonoverloaded_function )
{
char const * sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( uint a ) public returns ( uint ) { return 2 * a ; }
function g ( ) public returns ( uint ) { var x = f ; return x ( 7 ) ; }
2015-04-15 15:40:50 +00:00
}
) " ;
2017-08-28 18:40:38 +00:00
CHECK_SUCCESS ( sourceCode ) ;
2015-04-15 15:40:50 +00:00
}
BOOST_AUTO_TEST_CASE ( assignment_of_overloaded_function )
{
char const * sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( uint ) { return 1 ; }
function f ( uint a ) public returns ( uint ) { return 2 * a ; }
function g ( ) public returns ( uint ) { var x = f ; return x ( 7 ) ; }
2015-04-15 15:40:50 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " No matching declaration found after variable lookup. " ) ;
2015-04-15 15:40:50 +00:00
}
BOOST_AUTO_TEST_CASE ( external_types_clash )
{
char const * sourceCode = R " (
contract base {
enum a { X }
2017-09-05 15:11:53 +00:00
function f ( a ) public { }
2015-04-15 15:40:50 +00:00
}
contract test is base {
2017-09-05 15:11:53 +00:00
function f ( uint8 a ) public { }
2015-04-15 15:40:50 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Function overload clash during conversion to external types for arguments. " ) ;
2015-04-15 15:40:50 +00:00
}
BOOST_AUTO_TEST_CASE ( override_changes_return_types )
{
char const * sourceCode = R " (
contract base {
2017-09-05 15:11:53 +00:00
function f ( uint a ) public returns ( uint ) { }
2015-04-15 15:40:50 +00:00
}
contract test is base {
2017-09-05 15:11:53 +00:00
function f ( uint a ) public returns ( uint8 ) { }
2015-04-15 15:40:50 +00:00
}
) " ;
2017-07-18 04:10:57 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Overriding function return types differ " ) ;
2015-04-15 15:40:50 +00:00
}
BOOST_AUTO_TEST_CASE ( multiple_constructors )
{
char const * sourceCode = R " (
contract test {
2017-09-05 15:11:53 +00:00
function test ( uint a ) public { }
function test ( ) public { }
2015-04-15 15:40:50 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , DeclarationError , " More than one constructor defined " ) ;
2015-04-15 15:40:50 +00:00
}
BOOST_AUTO_TEST_CASE ( equal_overload )
{
char const * sourceCode = R " (
2016-12-05 14:40:35 +00:00
contract C {
2017-09-05 15:11:53 +00:00
function test ( uint a ) public returns ( uint b ) { }
2015-04-15 15:40:50 +00:00
function test ( uint a ) external { }
}
) " ;
2018-02-09 22:54:05 +00:00
CHECK_ALLOW_MULTI ( sourceCode , ( vector < pair < Error : : Type , string > > {
{ Error : : Type : : DeclarationError , " Function with same name and arguments defined twice. " } ,
{ Error : : Type : : TypeError , " Overriding function visibility differs " }
} ) ) ;
2015-04-15 15:40:50 +00:00
}
2015-04-15 22:06:57 +00:00
BOOST_AUTO_TEST_CASE ( uninitialized_var )
{
char const * sourceCode = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( uint ) { var x ; return 2 ; }
2015-04-15 22:06:57 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Assignment necessary for type detection. " ) ;
2015-04-15 22:06:57 +00:00
}
2015-05-28 14:20:50 +00:00
BOOST_AUTO_TEST_CASE ( string )
{
char const * sourceCode = R " (
contract C {
string s ;
function f ( string x ) external { s = x ; }
}
) " ;
2015-10-15 14:46:02 +00:00
BOOST_CHECK_NO_THROW ( parseAndAnalyse ( sourceCode ) ) ;
2015-05-28 14:20:50 +00:00
}
2016-11-25 12:54:13 +00:00
BOOST_AUTO_TEST_CASE ( invalid_utf8_implicit )
2016-11-25 12:13:47 +00:00
{
char const * sourceCode = R " (
contract C {
string s = " \xa0 \x00 " ;
}
) " ;
2016-11-25 12:36:06 +00:00
CHECK_ERROR ( sourceCode , TypeError , " invalid UTF-8 " ) ;
2016-11-25 12:13:47 +00:00
}
2016-11-25 12:54:13 +00:00
BOOST_AUTO_TEST_CASE ( invalid_utf8_explicit )
{
char const * sourceCode = R " (
contract C {
string s = string ( " \xa0 \x00 " ) ;
}
) " ;
CHECK_ERROR ( sourceCode , TypeError , " Explicit type conversion not allowed " ) ;
}
2017-06-13 18:12:45 +00:00
BOOST_AUTO_TEST_CASE ( large_utf8_codepoint )
{
char const * sourceCode = R " (
contract C {
string s = " \xf0 \x9f \xa6 \x84 " ;
}
) " ;
CHECK_SUCCESS ( sourceCode ) ;
}
2015-05-28 14:20:50 +00:00
BOOST_AUTO_TEST_CASE ( string_index )
{
char const * sourceCode = R " (
contract C {
string s ;
2017-09-05 15:11:53 +00:00
function f ( ) public { var a = s [ 2 ] ; }
2015-05-28 14:20:50 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Index access for string is not possible. " ) ;
2015-05-28 14:20:50 +00:00
}
BOOST_AUTO_TEST_CASE ( string_length )
{
char const * sourceCode = R " (
contract C {
string s ;
2017-09-05 15:11:53 +00:00
function f ( ) public { var a = s . length ; }
2015-05-28 14:20:50 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Member \" length \" not found or not visible after argument-dependent lookup in string storage ref " ) ;
2015-05-28 14:20:50 +00:00
}
2015-06-03 14:14:23 +00:00
BOOST_AUTO_TEST_CASE ( negative_integers_to_signed_out_of_bound )
{
char const * sourceCode = R " (
contract test {
int8 public i = - 129 ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Type int_const -129 is not implicitly convertible to expected type int8. " ) ;
2015-06-03 14:14:23 +00:00
}
BOOST_AUTO_TEST_CASE ( negative_integers_to_signed_min )
{
char const * sourceCode = R " (
contract test {
int8 public i = - 128 ;
}
) " ;
2015-10-15 14:46:02 +00:00
BOOST_CHECK_NO_THROW ( parseAndAnalyse ( sourceCode ) ) ;
2015-06-03 14:14:23 +00:00
}
BOOST_AUTO_TEST_CASE ( positive_integers_to_signed_out_of_bound )
{
char const * sourceCode = R " (
contract test {
int8 public j = 128 ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Type int_const 128 is not implicitly convertible to expected type int8. " ) ;
2015-06-03 14:14:23 +00:00
}
BOOST_AUTO_TEST_CASE ( positive_integers_to_signed_out_of_bound_max )
{
char const * sourceCode = R " (
contract test {
int8 public j = 127 ;
}
) " ;
2015-10-15 14:46:02 +00:00
BOOST_CHECK_NO_THROW ( parseAndAnalyse ( sourceCode ) ) ;
2015-06-03 14:14:23 +00:00
}
2015-06-04 10:42:55 +00:00
BOOST_AUTO_TEST_CASE ( negative_integers_to_unsigned )
{
char const * sourceCode = R " (
contract test {
uint8 public x = - 1 ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Type int_const -1 is not implicitly convertible to expected type uint8. " ) ;
2015-06-04 10:42:55 +00:00
}
2015-06-04 12:09:19 +00:00
BOOST_AUTO_TEST_CASE ( positive_integers_to_unsigned_out_of_bound )
{
char const * sourceCode = R " (
contract test {
uint8 public x = 700 ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Type int_const 700 is not implicitly convertible to expected type uint8. " ) ;
2015-06-04 12:09:19 +00:00
}
2015-08-06 13:33:06 +00:00
BOOST_AUTO_TEST_CASE ( integer_boolean_operators )
{
char const * sourceCode1 = R " (
2017-09-05 15:11:53 +00:00
contract test { function ( ) public { uint x = 1 ; uint y = 2 ; x | | y ; } }
2015-08-06 13:33:06 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode1 , TypeError , " Operator || not compatible with types uint256 and uint256 " ) ;
2015-08-06 13:33:06 +00:00
char const * sourceCode2 = R " (
2017-09-05 15:11:53 +00:00
contract test { function ( ) public { uint x = 1 ; uint y = 2 ; x & & y ; } }
2015-08-06 13:33:06 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode2 , TypeError , " Operator && not compatible with types uint256 and uint256 " ) ;
2015-08-06 13:33:06 +00:00
char const * sourceCode3 = R " (
2017-09-05 15:11:53 +00:00
contract test { function ( ) public { uint x = 1 ; ! x ; } }
2015-08-06 13:33:06 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode3 , TypeError , " Unary operator ! cannot be applied to type uint256 " ) ;
2015-08-06 13:33:06 +00:00
}
2016-10-24 16:40:22 +00:00
BOOST_AUTO_TEST_CASE ( exp_signed_variable )
{
char const * sourceCode1 = R " (
2017-09-05 15:11:53 +00:00
contract test { function ( ) public { uint x = 3 ; int y = - 4 ; x * * y ; } }
2016-10-24 16:40:22 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode1 , TypeError , " Operator ** not compatible with types uint256 and int256 " ) ;
2016-10-24 16:40:22 +00:00
char const * sourceCode2 = R " (
2017-09-05 15:11:53 +00:00
contract test { function ( ) public { uint x = 3 ; int y = - 4 ; y * * x ; } }
2016-10-24 16:40:22 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode2 , TypeError , " Operator ** not compatible with types int256 and uint256 " ) ;
2016-10-24 16:40:22 +00:00
char const * sourceCode3 = R " (
2017-09-05 15:11:53 +00:00
contract test { function ( ) public { int x = - 3 ; int y = - 4 ; x * * y ; } }
2016-10-24 16:40:22 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode3 , TypeError , " Operator ** not compatible with types int256 and int256 " ) ;
2016-10-24 16:40:22 +00:00
}
2015-08-06 13:39:42 +00:00
BOOST_AUTO_TEST_CASE ( reference_compare_operators )
{
char const * sourceCode1 = R " (
2017-09-05 15:11:53 +00:00
contract test { bytes a ; bytes b ; function ( ) public { a = = b ; } }
2015-08-06 13:39:42 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode1 , TypeError , " Operator == not compatible with types bytes storage ref and bytes storage ref " ) ;
2015-08-06 13:39:42 +00:00
char const * sourceCode2 = R " (
2017-09-05 15:11:53 +00:00
contract test { struct s { uint a ; } s x ; s y ; function ( ) public { x = = y ; } }
2015-08-06 13:39:42 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode2 , TypeError , " Operator == not compatible with types struct test.s storage ref and struct test.s storage ref " ) ;
2015-08-06 13:39:42 +00:00
}
2015-06-05 09:07:50 +00:00
BOOST_AUTO_TEST_CASE ( overwrite_memory_location_external )
{
char const * sourceCode = R " (
contract C {
function f ( uint [ ] memory a ) external { }
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Location has to be calldata for external functions (remove the \" memory \" or \" storage \" keyword). " ) ;
2015-06-05 09:07:50 +00:00
}
BOOST_AUTO_TEST_CASE ( overwrite_storage_location_external )
{
char const * sourceCode = R " (
contract C {
function f ( uint [ ] storage a ) external { }
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Location has to be calldata for external functions (remove the \" memory \" or \" storage \" keyword). " ) ;
2015-06-05 09:07:50 +00:00
}
BOOST_AUTO_TEST_CASE ( storage_location_local_variables )
{
char const * sourceCode = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-06-05 09:07:50 +00:00
uint [ ] storage x ;
uint [ ] memory y ;
uint [ ] memory z ;
2017-04-14 14:48:59 +00:00
x ; y ; z ;
2015-06-05 09:07:50 +00:00
}
}
) " ;
2015-10-15 14:46:02 +00:00
BOOST_CHECK_NO_THROW ( parseAndAnalyse ( sourceCode ) ) ;
2015-06-05 09:07:50 +00:00
}
2015-06-26 16:35:43 +00:00
BOOST_AUTO_TEST_CASE ( no_mappings_in_memory_array )
{
char const * sourceCode = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-06-26 16:35:43 +00:00
mapping ( uint = > uint ) [ ] memory x ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Type mapping(uint256 => uint256)[] memory is only valid in storage. " ) ;
2015-06-26 16:35:43 +00:00
}
2015-06-09 12:26:08 +00:00
BOOST_AUTO_TEST_CASE ( assignment_mem_to_local_storage_variable )
{
char const * sourceCode = R " (
contract C {
uint [ ] data ;
2017-09-05 15:11:53 +00:00
function f ( uint [ ] x ) public {
2015-06-09 12:26:08 +00:00
var dataRef = data ;
dataRef = x ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Type uint256[] memory is not implicitly convertible to expected type uint256[] storage pointer. " ) ;
2015-06-09 12:26:08 +00:00
}
BOOST_AUTO_TEST_CASE ( storage_assign_to_different_local_variable )
{
char const * sourceCode = R " (
contract C {
uint [ ] data ;
uint8 [ ] otherData ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-06-09 12:26:08 +00:00
uint8 [ ] storage x = otherData ;
uint [ ] storage y = data ;
y = x ;
// note that data = otherData works
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Type uint8[] storage pointer is not implicitly convertible to expected type uint256[] storage pointer. " ) ;
2015-06-09 12:26:08 +00:00
}
2017-03-03 17:44:15 +00:00
BOOST_AUTO_TEST_CASE ( uninitialized_mapping_variable )
{
char const * sourceCode = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-03-03 17:44:15 +00:00
mapping ( uint = > uint ) x ;
2017-04-14 14:48:59 +00:00
x ;
2017-03-03 17:44:15 +00:00
}
}
) " ;
CHECK_ERROR ( sourceCode , TypeError , " Uninitialized mapping. Mappings cannot be created dynamically, you have to assign them from a state variable " ) ;
}
BOOST_AUTO_TEST_CASE ( uninitialized_mapping_array_variable )
{
char const * sourceCode = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-07-05 17:38:00 +00:00
mapping ( uint = > uint ) [ ] storage x ;
2017-04-14 14:48:59 +00:00
x ;
2017-03-03 17:44:15 +00:00
}
}
) " ;
CHECK_WARNING ( sourceCode , " Uninitialized storage pointer " ) ;
}
2018-02-15 10:58:50 +00:00
BOOST_AUTO_TEST_CASE ( uninitialized_mapping_array_variable_050 )
{
char const * sourceCode = R " (
pragma experimental " v0.5.0 " ;
contract C {
function f ( ) pure public {
mapping ( uint = > uint ) [ ] storage x ;
x ;
}
}
) " ;
CHECK_ERROR ( sourceCode , DeclarationError , " Uninitialized storage pointer " ) ;
}
2015-06-26 16:35:43 +00:00
BOOST_AUTO_TEST_CASE ( no_delete_on_storage_pointers )
{
char const * sourceCode = R " (
contract C {
uint [ ] data ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-06-26 16:35:43 +00:00
var x = data ;
delete x ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Unary operator delete cannot be applied to type uint256[] storage pointer " ) ;
2015-06-26 16:35:43 +00:00
}
2015-06-09 12:26:08 +00:00
BOOST_AUTO_TEST_CASE ( assignment_mem_storage_variable_directly )
{
char const * sourceCode = R " (
contract C {
uint [ ] data ;
2017-09-05 15:11:53 +00:00
function f ( uint [ ] x ) public {
2015-06-09 12:26:08 +00:00
data = x ;
}
}
) " ;
2015-10-15 14:46:02 +00:00
BOOST_CHECK_NO_THROW ( parseAndAnalyse ( sourceCode ) ) ;
2015-06-09 12:26:08 +00:00
}
BOOST_AUTO_TEST_CASE ( function_argument_mem_to_storage )
{
char const * sourceCode = R " (
contract C {
function f ( uint [ ] storage x ) private {
}
2017-09-05 15:11:53 +00:00
function g ( uint [ ] x ) public {
2015-06-09 12:26:08 +00:00
f ( x ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Invalid type for argument in function call. Invalid implicit conversion from uint256[] memory to uint256[] storage pointer requested. " ) ;
2015-06-09 12:26:08 +00:00
}
BOOST_AUTO_TEST_CASE ( function_argument_storage_to_mem )
{
char const * sourceCode = R " (
contract C {
function f ( uint [ ] storage x ) private {
g ( x ) ;
}
2017-09-05 15:11:53 +00:00
function g ( uint [ ] x ) public {
2015-06-09 12:26:08 +00:00
}
}
) " ;
2015-10-15 14:46:02 +00:00
BOOST_CHECK_NO_THROW ( parseAndAnalyse ( sourceCode ) ) ;
2015-06-09 12:26:08 +00:00
}
BOOST_AUTO_TEST_CASE ( mem_array_assignment_changes_base_type )
{
// Such an assignment is possible in storage, but not in memory
// (because it would incur an otherwise unnecessary copy).
// This requirement might be lifted, though.
char const * sourceCode = R " (
contract C {
function f ( uint8 [ ] memory x ) private {
uint [ ] memory y = x ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Type uint8[] memory is not implicitly convertible to expected type uint256[] memory. " ) ;
2015-06-09 12:26:08 +00:00
}
2015-06-22 18:50:29 +00:00
BOOST_AUTO_TEST_CASE ( dynamic_return_types_not_possible )
{
char const * sourceCode = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( uint ) public returns ( string ) ;
function g ( ) public {
2015-10-09 17:35:41 +00:00
var ( x , ) = this . f ( 2 ) ;
2016-06-01 21:39:19 +00:00
// we can assign to x but it is not usable.
bytes ( x ) . length ;
2015-06-22 18:50:29 +00:00
}
}
) " ;
2018-02-21 14:59:34 +00:00
if ( dev : : test : : Options : : get ( ) . evmVersion ( ) = = EVMVersion : : homestead ( ) )
CHECK_ERROR ( sourceCode , TypeError , " Explicit type conversion not allowed from \" inaccessible dynamic type \" to \" bytes storage pointer \" . " ) ;
else
CHECK_WARNING ( sourceCode , " Use of the \" var \" keyword is deprecated " ) ;
2015-06-22 18:50:29 +00:00
}
2015-06-29 18:05:41 +00:00
BOOST_AUTO_TEST_CASE ( memory_arrays_not_resizeable )
{
char const * sourceCode = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-06-29 18:05:41 +00:00
uint [ ] memory x ;
x . length = 2 ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Expression has to be an lvalue. " ) ;
2015-06-29 18:05:41 +00:00
}
2015-06-30 19:08:34 +00:00
BOOST_AUTO_TEST_CASE ( struct_constructor )
{
char const * sourceCode = R " (
contract C {
struct S { uint a ; bool x ; }
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-06-30 19:08:34 +00:00
S memory s = S ( 1 , true ) ;
}
}
) " ;
2015-10-15 14:46:02 +00:00
BOOST_CHECK_NO_THROW ( parseAndAnalyse ( sourceCode ) ) ;
2015-06-30 19:08:34 +00:00
}
BOOST_AUTO_TEST_CASE ( struct_constructor_nested )
{
char const * sourceCode = R " (
contract C {
struct X { uint x1 ; uint x2 ; }
struct S { uint s1 ; uint [ 3 ] s2 ; X s3 ; }
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-06-30 19:08:34 +00:00
uint [ 3 ] memory s2 ;
S memory s = S ( 1 , s2 , X ( 4 , 5 ) ) ;
}
}
) " ;
2015-10-15 14:46:02 +00:00
BOOST_CHECK_NO_THROW ( parseAndAnalyse ( sourceCode ) ) ;
2015-06-30 19:08:34 +00:00
}
BOOST_AUTO_TEST_CASE ( struct_named_constructor )
{
char const * sourceCode = R " (
contract C {
struct S { uint a ; bool x ; }
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-06-30 19:08:34 +00:00
S memory s = S ( { a : 1 , x : true } ) ;
}
}
) " ;
2015-10-15 14:46:02 +00:00
BOOST_CHECK_NO_THROW ( parseAndAnalyse ( sourceCode ) ) ;
2015-06-30 19:08:34 +00:00
}
2015-07-07 23:13:56 +00:00
BOOST_AUTO_TEST_CASE ( literal_strings )
{
char const * text = R " (
contract Foo {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-07-07 23:13:56 +00:00
string memory long = " 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 " ;
string memory short = " 123 " ;
2017-04-14 14:48:59 +00:00
long ; short ;
2015-07-07 23:13:56 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-07-07 23:13:56 +00:00
}
2015-07-15 23:06:19 +00:00
BOOST_AUTO_TEST_CASE ( memory_structs_with_mappings )
{
char const * text = R " (
contract Test {
struct S { uint8 a ; mapping ( uint = > uint ) b ; uint8 c ; }
S s ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-07-15 23:06:19 +00:00
S memory x ;
x . b [ 1 ] ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" b \" is not available in struct Test.S memory outside of storage. " ) ;
2015-07-15 23:06:19 +00:00
}
2015-08-05 22:31:35 +00:00
BOOST_AUTO_TEST_CASE ( string_bytes_conversion )
{
char const * text = R " (
contract Test {
string s ;
bytes b ;
function h ( string _s ) external { bytes ( _s ) . length ; }
function i ( string _s ) internal { bytes ( _s ) . length ; }
function j ( ) internal { bytes ( s ) . length ; }
function k ( bytes _b ) external { string ( _b ) ; }
function l ( bytes _b ) internal { string ( _b ) ; }
function m ( ) internal { string ( b ) ; }
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-08-05 22:31:35 +00:00
}
2015-09-08 14:48:33 +00:00
BOOST_AUTO_TEST_CASE ( inheriting_from_library )
{
char const * text = R " (
library Lib { }
contract Test is Lib { }
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Libraries cannot be inherited from. " ) ;
2015-09-08 14:48:33 +00:00
}
BOOST_AUTO_TEST_CASE ( inheriting_library )
{
char const * text = R " (
contract Test { }
library Lib is Test { }
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Library is not allowed to inherit. " ) ;
2015-09-08 14:48:33 +00:00
}
BOOST_AUTO_TEST_CASE ( library_having_variables )
{
char const * text = R " (
library Lib { uint x ; }
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Library cannot have non-constant state variables " ) ;
2015-09-08 14:48:33 +00:00
}
2017-08-16 21:19:08 +00:00
BOOST_AUTO_TEST_CASE ( library_constructor )
{
char const * text = R " (
library Lib {
function Lib ( ) ;
}
) " ;
2018-02-09 22:54:05 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , ( vector < std : : string > {
" Constructor cannot be defined in libraries. " ,
" Constructor must be implemented if declared. "
} ) ) ;
2017-08-16 21:19:08 +00:00
}
2015-09-08 14:48:33 +00:00
BOOST_AUTO_TEST_CASE ( valid_library )
{
char const * text = R " (
library Lib { uint constant x = 9 ; }
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-09-08 14:48:33 +00:00
}
2015-09-10 15:17:13 +00:00
2015-09-10 17:40:07 +00:00
BOOST_AUTO_TEST_CASE ( call_to_library_function )
{
char const * text = R " (
library Lib {
2017-09-05 15:11:53 +00:00
function min ( uint , uint ) public returns ( uint ) ;
2015-09-10 17:40:07 +00:00
}
contract Test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-04 07:14:44 +00:00
uint t = Lib . min ( 12 , 7 ) ;
2015-09-10 17:40:07 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-09-10 17:40:07 +00:00
}
2015-09-10 15:17:13 +00:00
BOOST_AUTO_TEST_CASE ( creating_contract_within_the_contract )
{
char const * sourceCode = R " (
contract Test {
2017-09-05 15:11:53 +00:00
function f ( ) public { var x = new Test ( ) ; }
2015-09-11 11:39:25 +00:00
}
2015-09-10 15:17:13 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Circular reference for contract creation (cannot create instance of derived or same contract). " ) ;
2015-09-10 15:17:13 +00:00
}
2015-09-15 09:41:40 +00:00
BOOST_AUTO_TEST_CASE ( array_out_of_bound_access )
{
char const * text = R " (
2015-09-15 10:06:16 +00:00
contract c {
uint [ 2 ] dataArray ;
2017-09-05 15:11:53 +00:00
function set5th ( ) public returns ( bool ) {
2015-09-15 10:06:16 +00:00
dataArray [ 5 ] = 2 ;
return true ;
}
2015-09-15 09:41:40 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Out of bounds array access. " ) ;
2015-09-15 09:41:40 +00:00
}
2015-09-23 15:25:59 +00:00
BOOST_AUTO_TEST_CASE ( literal_string_to_storage_pointer )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public { string x = " abc " ; }
2015-09-23 15:25:59 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Type literal_string \" abc \" is not implicitly convertible to expected type string storage pointer. " ) ;
2015-09-23 15:25:59 +00:00
}
2015-09-24 11:58:51 +00:00
BOOST_AUTO_TEST_CASE ( non_initialized_references )
{
char const * text = R " (
contract c
{
2017-09-05 15:11:53 +00:00
struct s {
2015-09-24 11:58:51 +00:00
uint a ;
}
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-05 17:38:00 +00:00
s storage x ;
2015-09-24 11:58:51 +00:00
x . a = 2 ;
}
}
) " ;
2015-10-14 18:37:41 +00:00
2016-11-21 18:31:31 +00:00
CHECK_WARNING ( text , " Uninitialized storage pointer " ) ;
2015-09-24 11:58:51 +00:00
}
2018-02-15 10:58:50 +00:00
BOOST_AUTO_TEST_CASE ( non_initialized_references_050 )
{
char const * text = R " (
pragma experimental " v0.5.0 " ;
contract c
{
struct s {
uint a ;
}
function f ( ) public {
s storage x ;
}
}
) " ;
CHECK_ERROR ( text , DeclarationError , " Uninitialized storage pointer " ) ;
}
2017-05-11 12:43:29 +00:00
BOOST_AUTO_TEST_CASE ( keccak256_with_large_integer_constant )
2015-10-07 15:32:05 +00:00
{
char const * text = R " (
contract c
{
2017-09-05 15:11:53 +00:00
function f ( ) public { keccak256 ( 2 * * 500 ) ; }
2015-10-07 15:32:05 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Invalid rational number (too large or division by zero). " ) ;
2015-10-07 15:32:05 +00:00
}
2015-10-07 13:57:17 +00:00
BOOST_AUTO_TEST_CASE ( cyclic_binary_dependency )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract A { function f ( ) public { new B ( ) ; } }
contract B { function f ( ) public { new C ( ) ; } }
contract C { function f ( ) public { new A ( ) ; } }
2015-10-07 13:57:17 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Circular reference for contract creation (cannot create instance of derived or same contract). " ) ;
2015-10-07 13:57:17 +00:00
}
BOOST_AUTO_TEST_CASE ( cyclic_binary_dependency_via_inheritance )
{
char const * text = R " (
contract A is B { }
2017-09-05 15:11:53 +00:00
contract B { function f ( ) public { new C ( ) ; } }
contract C { function f ( ) public { new A ( ) ; } }
2015-10-07 13:57:17 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Definition of base has to precede definition of derived contract " ) ;
2015-10-07 13:57:17 +00:00
}
2015-10-09 14:26:27 +00:00
BOOST_AUTO_TEST_CASE ( multi_variable_declaration_fail )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract C { function f ( ) public { var ( x , y ) ; x = 1 ; y = 1 ; } }
2015-10-09 14:26:27 +00:00
) " ;
2017-04-14 14:48:59 +00:00
CHECK_ERROR ( text , TypeError , " Assignment necessary for type detection. " ) ;
2015-10-09 14:26:27 +00:00
}
2015-10-09 18:44:56 +00:00
BOOST_AUTO_TEST_CASE ( multi_variable_declaration_wildcards_fine )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function three ( ) public returns ( uint , uint , uint ) ;
function two ( ) public returns ( uint , uint ) ;
2015-10-13 10:22:57 +00:00
function none ( ) ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-10-09 18:44:56 +00:00
var ( a , ) = three ( ) ;
var ( b , c , ) = two ( ) ;
var ( , d ) = three ( ) ;
var ( , e , g ) = two ( ) ;
2015-10-13 10:22:57 +00:00
var ( , , ) = three ( ) ;
var ( ) = none ( ) ;
2017-04-14 14:48:59 +00:00
a ; b ; c ; d ; e ; g ;
2015-10-13 12:31:24 +00:00
}
2015-10-09 18:44:56 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-10-09 18:44:56 +00:00
}
BOOST_AUTO_TEST_CASE ( multi_variable_declaration_wildcards_fail_1 )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function one ( ) public returns ( uint ) ;
function f ( ) public { var ( a , b , ) = one ( ) ; }
2015-10-09 18:44:56 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Not enough components (1) in value to assign all variables (2). " ) ;
2015-10-09 18:44:56 +00:00
}
BOOST_AUTO_TEST_CASE ( multi_variable_declaration_wildcards_fail_2 )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function one ( ) public returns ( uint ) ;
function f ( ) public { var ( a , , ) = one ( ) ; }
2015-10-09 18:44:56 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Not enough components (1) in value to assign all variables (2). " ) ;
2015-10-09 18:44:56 +00:00
}
BOOST_AUTO_TEST_CASE ( multi_variable_declaration_wildcards_fail_3 )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function one ( ) public returns ( uint ) ;
function f ( ) public { var ( , , a ) = one ( ) ; }
2015-10-09 18:44:56 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Not enough components (1) in value to assign all variables (2). " ) ;
2015-10-09 18:44:56 +00:00
}
BOOST_AUTO_TEST_CASE ( multi_variable_declaration_wildcards_fail_4 )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function one ( ) public returns ( uint ) ;
function f ( ) public { var ( , a , b ) = one ( ) ; }
2015-10-09 18:44:56 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Not enough components (1) in value to assign all variables (2). " ) ;
2015-10-09 18:44:56 +00:00
}
2015-10-12 21:02:35 +00:00
BOOST_AUTO_TEST_CASE ( tuples )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-10-12 21:02:35 +00:00
uint a = ( 1 ) ;
2017-06-22 14:54:24 +00:00
var ( b , ) = ( uint8 ( 1 ) , ) ;
var ( c , d ) = ( uint32 ( 1 ) , 2 + a ) ;
var ( e , ) = ( uint64 ( 1 ) , 2 , b ) ;
2017-04-14 14:48:59 +00:00
a ; b ; c ; d ; e ;
2015-10-12 21:02:35 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-10-12 21:02:35 +00:00
}
BOOST_AUTO_TEST_CASE ( tuples_empty_components )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-10-12 21:02:35 +00:00
( 1 , , 2 ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Tuple component cannot be empty. " ) ;
2015-10-12 21:02:35 +00:00
}
2015-10-13 10:22:57 +00:00
BOOST_AUTO_TEST_CASE ( multi_variable_declaration_wildcards_fail_5 )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function one ( ) public returns ( uint ) ;
function f ( ) public { var ( , ) = one ( ) ; }
2015-10-13 10:22:57 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Wildcard both at beginning and end of variable declaration list is only allowed if the number of components is equal. " ) ;
2015-10-13 10:22:57 +00:00
}
BOOST_AUTO_TEST_CASE ( multi_variable_declaration_wildcards_fail_6 )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function two ( ) public returns ( uint , uint ) ;
function f ( ) public { var ( a , b , c ) = two ( ) ; }
2015-10-13 10:22:57 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Not enough components (2) in value to assign all variables (3) " ) ;
2015-10-13 10:22:57 +00:00
}
2017-03-01 14:42:41 +00:00
BOOST_AUTO_TEST_CASE ( tuple_assignment_from_void_function )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public { }
function g ( ) public {
2017-03-01 14:42:41 +00:00
var ( x , ) = ( f ( ) , f ( ) ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Cannot declare variable with void (empty tuple) type. " ) ;
}
2017-03-06 13:49:51 +00:00
BOOST_AUTO_TEST_CASE ( tuple_compound_assignment )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( uint a , uint b ) {
2017-03-06 13:49:51 +00:00
( a , b ) + = ( 1 , 1 ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Compound assignment is not allowed for tuple types. " ) ;
}
2015-10-16 14:12:14 +00:00
BOOST_AUTO_TEST_CASE ( member_access_parser_ambiguity )
{
char const * text = R " (
contract C {
struct R { uint [ 10 ] [ 10 ] y ; }
struct S { uint a ; uint b ; uint [ 20 ] [ 20 ] [ 20 ] c ; R d ; }
S data ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-10-16 14:12:14 +00:00
C . S x = data ;
C . S memory y ;
C . S [ 10 ] memory z ;
C . S [ 10 ] ;
y . a = 2 ;
x . c [ 1 ] [ 2 ] [ 3 ] = 9 ;
x . d . y [ 2 ] [ 2 ] = 3 ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-10-16 14:12:14 +00:00
}
2015-11-22 19:39:10 +00:00
BOOST_AUTO_TEST_CASE ( using_for_library )
{
char const * text = R " (
library D { }
contract C {
using D for uint ;
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-11-22 19:39:10 +00:00
}
BOOST_AUTO_TEST_CASE ( using_for_not_library )
{
char const * text = R " (
contract D { }
contract C {
using D for uint ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Library name expected. " ) ;
2015-11-22 19:39:10 +00:00
}
2015-11-25 13:23:35 +00:00
BOOST_AUTO_TEST_CASE ( using_for_function_exists )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
library D { function double ( uint self ) public returns ( uint ) { return 2 * self ; } }
2015-11-25 13:23:35 +00:00
contract C {
using D for uint ;
2017-09-05 15:11:53 +00:00
function f ( uint a ) public {
2015-11-25 13:23:35 +00:00
a . double ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-11-25 13:23:35 +00:00
}
BOOST_AUTO_TEST_CASE ( using_for_function_on_int )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
library D { function double ( uint self ) public returns ( uint ) { return 2 * self ; } }
2015-11-25 13:23:35 +00:00
contract C {
using D for uint ;
2017-09-05 15:11:53 +00:00
function f ( uint a ) public returns ( uint ) {
2015-11-25 13:23:35 +00:00
return a . double ( ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-11-25 13:23:35 +00:00
}
BOOST_AUTO_TEST_CASE ( using_for_function_on_struct )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
library D { struct s { uint a ; } function mul ( s storage self , uint x ) public returns ( uint ) { return self . a * = x ; } }
2015-11-25 13:23:35 +00:00
contract C {
using D for D . s ;
D . s x ;
2017-09-05 15:11:53 +00:00
function f ( uint a ) public returns ( uint ) {
2015-11-25 13:23:35 +00:00
return x . mul ( a ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-11-25 13:23:35 +00:00
}
BOOST_AUTO_TEST_CASE ( using_for_overload )
{
char const * text = R " (
library D {
struct s { uint a ; }
2017-09-05 15:11:53 +00:00
function mul ( s storage self , uint x ) public returns ( uint ) { return self . a * = x ; }
function mul ( s storage , bytes32 ) public returns ( bytes32 ) { }
2015-11-25 13:23:35 +00:00
}
contract C {
using D for D . s ;
D . s x ;
2017-09-05 15:11:53 +00:00
function f ( uint a ) public returns ( uint ) {
2015-11-25 13:23:35 +00:00
return x . mul ( a ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-11-25 13:23:35 +00:00
}
BOOST_AUTO_TEST_CASE ( using_for_by_name )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
library D { struct s { uint a ; } function mul ( s storage self , uint x ) public returns ( uint ) { return self . a * = x ; } }
2015-11-25 13:23:35 +00:00
contract C {
using D for D . s ;
D . s x ;
2017-09-05 15:11:53 +00:00
function f ( uint a ) public returns ( uint ) {
2015-11-25 13:23:35 +00:00
return x . mul ( { x : a } ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-11-25 13:23:35 +00:00
}
2015-11-27 21:24:00 +00:00
BOOST_AUTO_TEST_CASE ( using_for_mismatch )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
library D { function double ( bytes32 self ) public returns ( uint ) { return 2 ; } }
2015-11-27 21:24:00 +00:00
contract C {
using D for uint ;
2017-09-05 15:11:53 +00:00
function f ( uint a ) public returns ( uint ) {
2015-11-27 21:24:00 +00:00
return a . double ( ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" double \" not found or not visible after argument-dependent lookup in uint256 " ) ;
2015-11-27 21:24:00 +00:00
}
BOOST_AUTO_TEST_CASE ( using_for_not_used )
{
// This is an error because the function is only bound to uint.
// Had it been bound to *, it would have worked.
char const * text = R " (
2017-09-05 15:11:53 +00:00
library D { function double ( uint self ) public returns ( uint ) { return 2 ; } }
2015-11-27 21:24:00 +00:00
contract C {
using D for uint ;
2017-09-05 15:11:53 +00:00
function f ( uint16 a ) public returns ( uint ) {
2015-11-27 21:24:00 +00:00
return a . double ( ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" double \" not found or not visible after argument-dependent lookup in uint16 " ) ;
2016-11-22 16:09:22 +00:00
}
BOOST_AUTO_TEST_CASE ( library_memory_struct )
{
char const * text = R " (
2017-12-11 02:39:39 +00:00
pragma experimental ABIEncoderV2 ;
2016-11-22 16:09:22 +00:00
library c {
struct S { uint x ; }
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( S ) { }
2016-11-22 16:09:22 +00:00
}
) " ;
2017-06-01 10:26:13 +00:00
CHECK_SUCCESS ( text ) ;
2015-11-27 21:24:00 +00:00
}
BOOST_AUTO_TEST_CASE ( using_for_arbitrary_mismatch )
{
// Bound to a, but self type does not match.
char const * text = R " (
2017-09-05 15:11:53 +00:00
library D { function double ( bytes32 self ) public returns ( uint ) { return 2 ; } }
2015-11-27 21:24:00 +00:00
contract C {
using D for * ;
2017-09-05 15:11:53 +00:00
function f ( uint a ) public returns ( uint ) {
2015-11-27 21:24:00 +00:00
return a . double ( ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" double \" not found or not visible after argument-dependent lookup in uint256 " ) ;
2015-11-27 21:24:00 +00:00
}
2015-11-25 13:23:35 +00:00
BOOST_AUTO_TEST_CASE ( bound_function_in_var )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
library D { struct s { uint a ; } function mul ( s storage self , uint x ) public returns ( uint ) { return self . a * = x ; } }
2015-11-25 13:23:35 +00:00
contract C {
using D for D . s ;
D . s x ;
2017-09-05 15:11:53 +00:00
function f ( uint a ) public returns ( uint ) {
2015-11-25 13:23:35 +00:00
var g = x . mul ;
return g ( { x : a } ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-11-25 13:23:35 +00:00
}
2015-11-16 23:06:57 +00:00
BOOST_AUTO_TEST_CASE ( create_memory_arrays )
{
char const * text = R " (
library L {
struct R { uint [ 10 ] [ 10 ] y ; }
struct S { uint a ; uint b ; uint [ 20 ] [ 20 ] [ 20 ] c ; R d ; }
}
contract C {
2017-09-05 15:11:53 +00:00
function f ( uint size ) public {
2015-11-17 00:47:47 +00:00
L . S [ ] [ ] memory x = new L . S [ ] [ ] ( 10 ) ;
2015-11-16 23:06:57 +00:00
var y = new uint [ ] ( 20 ) ;
var z = new bytes ( size ) ;
2017-04-14 14:48:59 +00:00
x ; y ; z ;
2015-11-16 23:06:57 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-11-16 23:06:57 +00:00
}
2015-11-17 00:47:47 +00:00
BOOST_AUTO_TEST_CASE ( mapping_in_memory_array )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( uint size ) public {
2015-11-17 00:47:47 +00:00
var x = new mapping ( uint = > uint ) [ ] ( 4 ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Type cannot live outside storage. " ) ;
2015-11-17 00:47:47 +00:00
}
BOOST_AUTO_TEST_CASE ( new_for_non_array )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( uint size ) public {
2015-11-17 00:47:47 +00:00
var x = new uint ( 7 ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Contract or array type expected. " ) ;
2015-11-17 00:47:47 +00:00
}
BOOST_AUTO_TEST_CASE ( invalid_args_creating_memory_array )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( uint size ) public {
2015-11-17 00:47:47 +00:00
var x = new uint [ ] ( ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Wrong argument count for function call: 0 arguments given but expected 1. " ) ;
2015-11-17 00:47:47 +00:00
}
2018-01-04 10:24:39 +00:00
BOOST_AUTO_TEST_CASE ( invalid_args_creating_struct )
{
char const * text = R " (
contract C {
struct S { uint a ; uint b ; }
function f ( ) public {
var s = S ( { a : 1 } ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Wrong argument count for struct constructor: 1 arguments given but expected 2. " ) ;
}
2015-12-18 12:56:37 +00:00
BOOST_AUTO_TEST_CASE ( function_overload_array_type )
{
char const * text = R " (
contract M {
2017-04-14 14:48:59 +00:00
function f ( uint [ ] ) ;
function f ( int [ ] ) ;
2015-12-18 12:56:37 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-12-18 12:56:37 +00:00
}
2016-01-10 07:07:02 +00:00
BOOST_AUTO_TEST_CASE ( inline_array_declaration_and_passing_implicit_conversion )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( uint ) {
2016-01-10 07:07:02 +00:00
uint8 x = 7 ;
uint16 y = 8 ;
uint32 z = 9 ;
2016-02-18 22:39:11 +00:00
uint32 [ 3 ] memory ending = [ x , y , z ] ;
return ( ending [ 1 ] ) ;
2016-01-10 07:07:02 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-01-10 07:07:02 +00:00
}
BOOST_AUTO_TEST_CASE ( inline_array_declaration_and_passing_implicit_conversion_strings )
2015-12-15 20:47:09 +00:00
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( string ) {
2016-01-10 07:07:02 +00:00
string memory x = " Hello " ;
string memory y = " World " ;
string [ 2 ] memory z = [ x , y ] ;
return ( z [ 0 ] ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-01-10 07:07:02 +00:00
}
BOOST_AUTO_TEST_CASE ( inline_array_declaration_const_int_conversion )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( uint ) {
2016-01-10 07:07:02 +00:00
uint8 [ 4 ] memory z = [ 1 , 2 , 3 , 5 ] ;
return ( z [ 0 ] ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-01-10 07:07:02 +00:00
}
BOOST_AUTO_TEST_CASE ( inline_array_declaration_const_string_conversion )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( string ) {
2016-01-10 07:07:02 +00:00
string [ 2 ] memory z = [ " Hello " , " World " ] ;
return ( z [ 0 ] ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-01-10 07:07:02 +00:00
}
BOOST_AUTO_TEST_CASE ( inline_array_declaration_no_type )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( uint ) {
2016-01-10 07:07:02 +00:00
return ( [ 4 , 5 , 6 ] [ 1 ] ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-01-10 07:07:02 +00:00
}
BOOST_AUTO_TEST_CASE ( inline_array_declaration_no_type_strings )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( string ) {
2016-01-10 07:07:02 +00:00
return ( [ " foo " , " man " , " choo " ] [ 1 ] ) ;
}
2015-12-15 20:47:09 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-12-16 19:35:28 +00:00
}
2015-12-15 20:47:09 +00:00
2016-01-11 21:36:30 +00:00
BOOST_AUTO_TEST_CASE ( inline_struct_declaration_arrays )
{
char const * text = R " (
contract C {
struct S {
uint a ;
string b ;
}
function f ( ) {
S [ 2 ] memory x = [ S ( { a : 1 , b : " fish " } ) , S ( { a : 2 , b : " fish " } ) ] ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-01-11 21:36:30 +00:00
}
2015-12-15 20:47:09 +00:00
BOOST_AUTO_TEST_CASE ( invalid_types_in_inline_array )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-01-10 07:07:02 +00:00
uint [ 3 ] x = [ 45 , ' foo ' , true ] ;
2015-12-15 20:47:09 +00:00
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Unable to deduce common type for array elements. " ) ;
2016-01-10 07:07:02 +00:00
}
2015-12-15 20:47:09 +00:00
2016-01-11 20:25:59 +00:00
BOOST_AUTO_TEST_CASE ( dynamic_inline_array )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-01-12 05:41:20 +00:00
uint8 [ 4 ] [ 4 ] memory dyn = [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7]] ;
2016-01-11 20:25:59 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-01-11 20:25:59 +00:00
}
BOOST_AUTO_TEST_CASE ( lvalues_as_inline_array )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-01-11 20:25:59 +00:00
[ 1 , 2 , 3 ] + + ;
[ 1 , 2 , 3 ] = [ 4 , 5 , 6 ] ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Inline array type cannot be declared as LValue. " ) ;
2016-01-11 20:25:59 +00:00
}
2016-01-14 01:58:09 +00:00
BOOST_AUTO_TEST_CASE ( break_not_in_loop )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-01-14 01:58:09 +00:00
if ( true )
break ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , SyntaxError , " \" break \" has to be in a \" for \" or \" while \" loop. " ) ;
2016-01-14 01:58:09 +00:00
}
BOOST_AUTO_TEST_CASE ( continue_not_in_loop )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-01-14 01:58:09 +00:00
if ( true )
continue ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , SyntaxError , " \" continue \" has to be in a \" for \" or \" while \" loop. " ) ;
2016-01-14 01:58:09 +00:00
}
2016-01-19 02:18:01 +00:00
BOOST_AUTO_TEST_CASE ( continue_not_in_loop_2 )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-01-19 02:18:01 +00:00
while ( true )
{
}
continue ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , SyntaxError , " \" continue \" has to be in a \" for \" or \" while \" loop. " ) ;
2016-01-19 02:18:01 +00:00
}
2015-12-22 17:14:09 +00:00
BOOST_AUTO_TEST_CASE ( invalid_different_types_for_conditional_expression )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2015-12-22 17:14:09 +00:00
true ? true : 2 ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " True expression's type bool doesn't match false expression's type uint8. " ) ;
2015-12-22 17:14:09 +00:00
}
2016-01-11 07:08:28 +00:00
BOOST_AUTO_TEST_CASE ( left_value_in_conditional_expression_not_supported_yet )
2015-12-22 17:14:09 +00:00
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-01-11 07:08:28 +00:00
uint x ;
uint y ;
( true ? x : y ) = 1 ;
2015-12-22 17:14:09 +00:00
}
}
) " ;
2018-02-09 22:54:05 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , ( std : : vector < std : : string > {
" Conditional expression as left value is not supported yet. " ,
" Expression has to be an lvalue "
} ) ) ;
2015-12-22 17:14:09 +00:00
}
2016-01-15 02:19:11 +00:00
BOOST_AUTO_TEST_CASE ( conditional_expression_with_different_struct )
{
char const * text = R " (
contract C {
struct s1 {
uint x ;
}
struct s2 {
uint x ;
}
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-12-05 14:40:35 +00:00
s1 memory x ;
s2 memory y ;
2016-01-15 02:19:11 +00:00
true ? x : y ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " True expression's type struct C.s1 memory doesn't match false expression's type struct C.s2 memory. " ) ;
2016-01-15 02:19:11 +00:00
}
BOOST_AUTO_TEST_CASE ( conditional_expression_with_different_function_type )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function x ( bool ) public { }
function y ( ) public { }
2016-01-15 02:19:11 +00:00
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-01-15 02:19:11 +00:00
true ? x : y ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " True expression's type function (bool) doesn't match false expression's type function (). " ) ;
2016-01-15 02:19:11 +00:00
}
BOOST_AUTO_TEST_CASE ( conditional_expression_with_different_enum )
{
char const * text = R " (
contract C {
enum small { A , B , C , D }
enum big { A , B , C , D }
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-01-15 02:19:11 +00:00
small x ;
big y ;
true ? x : y ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " True expression's type enum C.small doesn't match false expression's type enum C.big. " ) ;
2016-01-15 02:19:11 +00:00
}
BOOST_AUTO_TEST_CASE ( conditional_expression_with_different_mapping )
{
char const * text = R " (
contract C {
mapping ( uint8 = > uint8 ) table1 ;
mapping ( uint32 = > uint8 ) table2 ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-01-15 02:19:11 +00:00
true ? table1 : table2 ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " True expression's type mapping(uint8 => uint8) doesn't match false expression's type mapping(uint32 => uint8). " ) ;
2016-01-15 02:19:11 +00:00
}
BOOST_AUTO_TEST_CASE ( conditional_with_all_types )
{
char const * text = R " (
contract C {
struct s1 {
uint x ;
}
s1 struct_x ;
s1 struct_y ;
2017-09-05 15:11:53 +00:00
function fun_x ( ) public { }
function fun_y ( ) public { }
2016-01-15 02:19:11 +00:00
enum small { A , B , C , D }
mapping ( uint8 = > uint8 ) table1 ;
mapping ( uint8 = > uint8 ) table2 ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-01-15 02:19:11 +00:00
// integers
uint x ;
uint y ;
2017-04-21 09:13:10 +00:00
uint g = true ? x : y ;
2017-04-14 14:48:59 +00:00
g + = 1 ; // Avoid unused var warning
2016-01-15 02:19:11 +00:00
// integer constants
2017-04-21 09:13:10 +00:00
uint h = true ? 1 : 3 ;
2017-04-14 14:48:59 +00:00
h + = 1 ; // Avoid unused var warning
2016-01-15 02:19:11 +00:00
// string literal
2017-04-21 09:13:10 +00:00
var i = true ? " hello " : " world " ;
2017-04-14 14:48:59 +00:00
i = " used " ; //Avoid unused var warning
2017-04-21 09:13:10 +00:00
}
2017-09-05 15:11:53 +00:00
function f2 ( ) public {
2016-01-15 02:19:11 +00:00
// bool
2017-04-21 09:13:10 +00:00
bool j = true ? true : false ;
2017-04-14 14:48:59 +00:00
j = j & & true ; // Avoid unused var warning
2016-01-15 02:19:11 +00:00
// real is not there yet.
// array
byte [ 2 ] memory a ;
byte [ 2 ] memory b ;
2017-04-21 09:13:10 +00:00
var k = true ? a : b ;
2017-06-22 14:14:14 +00:00
k [ 0 ] = byte ( 0 ) ; //Avoid unused var warning
2016-01-15 02:19:11 +00:00
bytes memory e ;
bytes memory f ;
2017-04-21 09:13:10 +00:00
var l = true ? e : f ;
2017-06-22 14:14:14 +00:00
l [ 0 ] = byte ( 0 ) ; // Avoid unused var warning
2016-01-15 02:19:11 +00:00
// fixed bytes
bytes2 c ;
bytes2 d ;
2017-04-21 09:13:10 +00:00
var m = true ? c : d ;
2017-04-14 14:48:59 +00:00
m & = m ;
2017-04-21 09:13:10 +00:00
}
2017-09-05 15:11:53 +00:00
function f3 ( ) public {
2016-01-15 02:19:11 +00:00
// contract doesn't fit in here
// struct
2017-04-21 09:13:10 +00:00
struct_x = true ? struct_x : struct_y ;
2016-01-15 02:19:11 +00:00
// function
2017-04-21 09:13:10 +00:00
var r = true ? fun_x : fun_y ;
2017-04-14 14:48:59 +00:00
r ( ) ; // Avoid unused var warning
2016-01-15 02:19:11 +00:00
// enum
small enum_x ;
small enum_y ;
2017-04-21 09:13:10 +00:00
enum_x = true ? enum_x : enum_y ;
2016-01-15 02:19:11 +00:00
// tuple
2017-04-21 09:13:10 +00:00
var ( n , o ) = true ? ( 1 , 2 ) : ( 3 , 4 ) ;
2017-04-14 14:48:59 +00:00
( n , o ) = ( o , n ) ; // Avoid unused var warning
2016-01-15 02:19:11 +00:00
// mapping
2017-04-21 09:13:10 +00:00
var p = true ? table1 : table2 ;
2017-04-14 14:48:59 +00:00
p [ 0 ] = 0 ; // Avoid unused var warning
2016-01-15 02:19:11 +00:00
// typetype
2017-04-21 09:13:10 +00:00
var q = true ? uint32 ( 1 ) : uint32 ( 2 ) ;
2017-04-14 14:48:59 +00:00
q + = 1 ; // Avoid unused var warning
2016-01-15 02:19:11 +00:00
// modifier doesn't fit in here
// magic doesn't fit in here
// module doesn't fit in here
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-01-15 02:19:11 +00:00
}
2016-02-03 20:34:24 +00:00
BOOST_AUTO_TEST_CASE ( index_access_for_bytes )
{
char const * text = R " (
contract C {
bytes20 x ;
2017-09-05 15:11:53 +00:00
function f ( bytes16 b ) public {
2016-02-03 20:34:24 +00:00
b [ uint ( x [ 2 ] ) ] ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-02-03 20:34:24 +00:00
}
2016-02-09 21:43:23 +00:00
BOOST_AUTO_TEST_CASE ( uint7_and_uintM_as_identifier )
{
char const * text = R " (
contract test {
string uintM = " Hello 4 you " ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-02-09 21:43:23 +00:00
uint8 uint7 = 3 ;
uint7 = 5 ;
string memory intM ;
uint bytesM = 21 ;
2017-04-14 14:48:59 +00:00
intM ; bytesM ;
2016-02-09 21:43:23 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-02-09 21:43:23 +00:00
}
BOOST_AUTO_TEST_CASE ( varM_disqualified_as_keyword )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-02-09 21:43:23 +00:00
uintM something = 3 ;
intM should = 4 ;
bytesM fail = " now " ;
}
}
) " ;
2018-02-09 22:54:05 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , DeclarationError , ( std : : vector < std : : string > {
" Identifier not found or not unique. " ,
" Identifier not found or not unique. " ,
" Identifier not found or not unique. "
} ) ) ;
2016-02-09 21:43:23 +00:00
}
2017-10-26 17:13:33 +00:00
BOOST_AUTO_TEST_CASE ( modifier_is_not_a_valid_typename )
{
char const * text = R " (
contract test {
modifier mod ( ) { _ ; }
function f ( ) public {
mod g ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Name has to refer to a struct, enum or contract. " ) ;
}
2018-01-04 14:45:44 +00:00
BOOST_AUTO_TEST_CASE ( modifier_is_not_a_valid_typename_is_not_fatal )
{
char const * text = R " (
contract test {
modifier mod ( ) { _ ; }
function f ( ) public {
mod g ;
g = f ;
}
}
) " ;
2018-02-09 22:54:05 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , ( std : : vector < std : : string > { " Name has to refer to a struct, enum or contract. " } ) ) ;
2018-01-04 14:45:44 +00:00
}
2017-10-26 17:13:33 +00:00
BOOST_AUTO_TEST_CASE ( function_is_not_a_valid_typename )
{
char const * text = R " (
contract test {
function foo ( ) public {
}
function f ( ) public {
foo g ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Name has to refer to a struct, enum or contract. " ) ;
}
2016-02-12 21:01:27 +00:00
BOOST_AUTO_TEST_CASE ( long_uint_variable_fails )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-02-12 21:01:27 +00:00
uint99999999999999999999999999 something = 3 ;
}
}
) " ;
2017-11-22 15:41:07 +00:00
CHECK_ERROR ( text , DeclarationError , " Identifier not found or not unique. " ) ;
2016-02-12 21:01:27 +00:00
}
2016-02-18 16:34:07 +00:00
BOOST_AUTO_TEST_CASE ( bytes10abc_is_identifier )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-02-18 16:34:07 +00:00
bytes32 bytes10abc = " abc " ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-02-18 16:34:07 +00:00
}
BOOST_AUTO_TEST_CASE ( int10abc_is_identifier )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-02-18 16:34:07 +00:00
uint uint10abc = 3 ;
int int10abc = 4 ;
2017-04-14 14:48:59 +00:00
uint10abc ; int10abc ;
2016-02-18 16:34:07 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-02-18 16:34:07 +00:00
}
2016-02-18 22:39:11 +00:00
BOOST_AUTO_TEST_CASE ( library_functions_do_not_have_value )
2016-03-10 19:25:14 +00:00
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
library L { function l ( ) public { } }
2016-03-10 19:25:14 +00:00
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-02-18 22:39:11 +00:00
L . l . value ;
2016-03-10 19:25:14 +00:00
}
}
) " ;
2017-11-22 15:41:07 +00:00
CHECK_ERROR ( text , TypeError , " Member \" value \" not found or not visible after argument-dependent lookup in function () " ) ;
2016-03-10 19:25:14 +00:00
}
2016-02-18 22:39:11 +00:00
BOOST_AUTO_TEST_CASE ( invalid_fixed_types_0x7_mxn )
2016-03-07 15:55:53 +00:00
{
char const * text = R " (
contract test {
2016-02-18 22:39:11 +00:00
fixed0x7 a = .3 ;
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , DeclarationError , " Identifier not found " ) ;
2016-02-18 22:39:11 +00:00
}
BOOST_AUTO_TEST_CASE ( invalid_fixed_types_long_invalid_identifier )
{
char const * text = R " (
contract test {
fixed99999999999999999999999999999999999999x7 b = 9.5 ;
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , DeclarationError , " Identifier not found " ) ;
2016-02-18 22:39:11 +00:00
}
BOOST_AUTO_TEST_CASE ( invalid_fixed_types_7x8_mxn )
{
char const * text = R " (
contract test {
fixed7x8 c = 3.12345678 ;
2016-03-07 15:55:53 +00:00
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , DeclarationError , " Identifier not found " ) ;
2016-03-07 15:55:53 +00:00
}
2016-05-03 20:48:53 +00:00
BOOST_AUTO_TEST_CASE ( library_instances_cannot_be_used )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
library L { function l ( ) public { } }
2016-05-03 20:48:53 +00:00
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-03 20:48:53 +00:00
L x ;
x . l ( ) ;
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " Member \" l \" not found or not visible after argument-dependent lookup in library L " ) ;
2016-05-03 20:48:53 +00:00
}
2016-03-30 14:52:33 +00:00
BOOST_AUTO_TEST_CASE ( invalid_fixed_type_long )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-03-30 14:52:33 +00:00
fixed8x888888888888888888888888888888888888888888888888888 b ;
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , DeclarationError , " Identifier not found " ) ;
2016-03-30 14:52:33 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( fixed_type_int_conversion )
2016-02-18 22:39:11 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
uint64 a = 3 ;
int64 b = 4 ;
2016-05-05 22:47:08 +00:00
fixed c = b ;
ufixed d = a ;
2017-04-14 14:48:59 +00:00
c ; d ;
2016-02-18 22:39:11 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-02-18 22:39:11 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( fixed_type_rational_int_conversion )
2016-02-18 22:39:11 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-05 22:47:08 +00:00
fixed c = 3 ;
ufixed d = 4 ;
2017-04-14 14:48:59 +00:00
c ; d ;
2016-02-18 22:39:11 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-02-18 22:39:11 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( fixed_type_rational_fraction_conversion )
2016-02-18 22:39:11 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-05 22:47:08 +00:00
fixed a = 4.5 ;
ufixed d = 2.5 ;
2017-04-14 14:48:59 +00:00
a ; d ;
2016-02-18 22:39:11 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-02-18 22:39:11 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( invalid_int_implicit_conversion_from_fixed )
2016-02-18 22:39:11 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-04-08 06:19:20 +00:00
fixed a = 4.5 ;
2016-05-05 22:47:08 +00:00
int b = a ;
2017-04-14 14:48:59 +00:00
a ; b ;
2016-05-05 22:47:08 +00:00
}
}
) " ;
2018-02-16 15:11:07 +00:00
CHECK_ERROR ( text , TypeError , " Type fixed128x18 is not implicitly convertible to expected type int256 " ) ;
2016-05-05 22:47:08 +00:00
}
BOOST_AUTO_TEST_CASE ( rational_unary_operation )
{
char const * text = R " (
2017-07-12 13:44:27 +00:00
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-07-12 13:44:27 +00:00
ufixed16x2 a = 3.25 ;
fixed16x2 b = - 3.25 ;
a ; b ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2017-09-20 15:52:10 +00:00
// Test deprecation warning under < 0.5.0
2017-07-12 13:44:27 +00:00
text = R " (
2016-05-05 22:47:08 +00:00
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2016-12-22 18:20:03 +00:00
ufixed16x2 a = + 3.25 ;
fixed16x2 b = - 3.25 ;
2017-07-12 13:44:27 +00:00
a ; b ;
2017-04-29 00:43:19 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_WARNING ( text , " Use of unary + is deprecated " ) ;
2017-05-02 13:48:58 +00:00
text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( uint x ) pure public {
2017-05-02 13:48:58 +00:00
uint y = + x ;
2017-05-03 09:30:40 +00:00
y ;
2017-05-02 13:48:58 +00:00
}
}
) " ;
CHECK_WARNING ( text , " Use of unary + is deprecated " ) ;
2017-09-20 15:52:10 +00:00
// Test syntax error under 0.5.0
text = R " (
pragma experimental " v0.5.0 " ;
contract test {
function f ( ) pure public {
ufixed16x2 a = + 3.25 ;
fixed16x2 b = - 3.25 ;
a ; b ;
}
}
) " ;
CHECK_ERROR ( text , SyntaxError , " Use of unary + is deprecated " ) ;
text = R " (
pragma experimental " v0.5.0 " ;
contract test {
function f ( uint x ) pure public {
uint y = + x ;
y ;
}
}
) " ;
CHECK_ERROR ( text , SyntaxError , " Use of unary + is deprecated " ) ;
2016-02-18 22:39:11 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( leading_zero_rationals_convert )
{
char const * text = R " (
contract A {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-07-12 13:44:27 +00:00
ufixed16x2 a = 0.5 ;
ufixed256x52 b = 0.0000000000000006661338147750939242541790008544921875 ;
fixed16x2 c = - 0.5 ;
fixed256x52 d = - 0.0000000000000006661338147750939242541790008544921875 ;
a ; b ; c ; d ;
2016-05-05 22:47:08 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-05-05 22:47:08 +00:00
}
BOOST_AUTO_TEST_CASE ( size_capabilities_of_fixed_point_types )
2016-02-18 22:39:11 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-12-22 18:20:03 +00:00
ufixed256x1 a = 123456781234567979695948382928485849359686494864095409282048094275023098123.5 ;
ufixed256x77 b = 0.920890746623327805482905058466021565416131529487595827354393978494366605267637 ;
ufixed224x78 c = 0.000000000001519884736399797998492268541131529487595827354393978494366605267646 ;
fixed256x1 d = - 123456781234567979695948382928485849359686494864095409282048094275023098123.5 ;
fixed256x76 e = - 0.93322335481643744342575580035176794825198893968114429702091846411734101080123 ;
fixed256x79 g = - 0.0001178860664374434257558003517679482519889396811442970209184641173410108012309 ;
2017-07-12 13:44:27 +00:00
a ; b ; c ; d ; e ; g ;
2016-12-22 18:20:03 +00:00
}
}
) " ;
CHECK_SUCCESS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( zero_handling )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
fixed16x2 a = 0 ; a ;
ufixed32x1 b = 0 ; b ;
2016-02-18 22:39:11 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-02-18 22:39:11 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( fixed_type_invalid_implicit_conversion_size )
2016-04-08 06:19:20 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-05 22:47:08 +00:00
ufixed a = 11 / 4 ;
2017-07-12 13:44:27 +00:00
ufixed248x8 b = a ; b ;
2016-04-08 06:19:20 +00:00
}
}
) " ;
2018-02-16 15:11:07 +00:00
CHECK_ERROR ( text , TypeError , " Type ufixed128x18 is not implicitly convertible to expected type ufixed248x8 " ) ;
2016-04-08 06:19:20 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( fixed_type_invalid_implicit_conversion_lost_data )
2016-03-18 20:03:26 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
ufixed256x1 a = 1 / 3 ; a ;
2016-03-18 20:03:26 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " is not implicitly convertible to expected type ufixed256x1 " ) ;
2016-03-18 20:03:26 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( fixed_type_valid_explicit_conversions )
2016-03-18 20:03:26 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
ufixed256x80 a = ufixed256x80 ( 1 / 3 ) ; a ;
ufixed248x80 b = ufixed248x80 ( 1 / 3 ) ; b ;
ufixed8x1 c = ufixed8x1 ( 1 / 3 ) ; c ;
2016-03-18 20:03:26 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-03-18 20:03:26 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( invalid_array_declaration_with_rational )
2016-02-18 22:39:11 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
uint [ 3.5 ] a ; a ;
2016-02-18 22:39:11 +00:00
}
}
) " ;
2017-10-02 21:59:39 +00:00
CHECK_ERROR ( text , TypeError , " Array with fractional length specified. " ) ;
2016-02-18 22:39:11 +00:00
}
2016-12-22 18:20:03 +00:00
BOOST_AUTO_TEST_CASE ( invalid_array_declaration_with_signed_fixed_type )
2016-02-18 22:39:11 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
uint [ fixed ( 3.5 ) ] a ; a ;
2016-02-18 22:39:11 +00:00
}
}
) " ;
2017-11-22 12:33:11 +00:00
CHECK_ERROR ( text , TypeError , " Invalid array length, expected integer literal or constant expression. " ) ;
2016-02-18 22:39:11 +00:00
}
2016-12-22 18:20:03 +00:00
BOOST_AUTO_TEST_CASE ( invalid_array_declaration_with_unsigned_fixed_type )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
uint [ ufixed ( 3.5 ) ] a ; a ;
2016-12-22 18:20:03 +00:00
}
}
) " ;
2017-11-22 12:33:11 +00:00
CHECK_ERROR ( text , TypeError , " Invalid array length, expected integer literal or constant expression. " ) ;
2016-12-22 18:20:03 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( rational_to_bytes_implicit_conversion )
2016-02-18 22:39:11 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
bytes32 c = 3.2 ; c ;
2016-02-18 22:39:11 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " is not implicitly convertible to expected type bytes32 " ) ;
2016-02-18 22:39:11 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( fixed_to_bytes_implicit_conversion )
2016-02-18 22:39:11 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-12-05 14:40:35 +00:00
fixed a = 3.25 ;
2017-07-12 13:44:27 +00:00
bytes32 c = a ; c ;
2016-02-18 22:39:11 +00:00
}
}
) " ;
2018-02-16 15:11:07 +00:00
CHECK_ERROR ( text , TypeError , " fixed128x18 is not implicitly convertible to expected type bytes32 " ) ;
2016-02-18 22:39:11 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( mapping_with_fixed_literal )
2016-02-18 22:39:11 +00:00
{
char const * text = R " (
contract test {
2016-12-22 18:20:03 +00:00
mapping ( ufixed8x1 = > string ) fixedString ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-05 22:47:08 +00:00
fixedString [ 0.5 ] = " Half " ;
2016-02-18 22:39:11 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-02-18 22:39:11 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( fixed_points_inside_structs )
2016-03-11 23:53:54 +00:00
{
char const * text = R " (
2016-05-05 22:47:08 +00:00
contract test {
struct myStruct {
ufixed a ;
int b ;
}
myStruct a = myStruct ( 3.125 , 3 ) ;
2016-03-11 23:53:54 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-03-11 23:53:54 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( inline_array_fixed_types )
2016-02-18 22:39:11 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-05 22:47:08 +00:00
fixed [ 3 ] memory a = [ fixed ( 3.5 ) , fixed ( - 4.25 ) , fixed ( 967.125 ) ] ;
2016-02-18 22:39:11 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-02-18 22:39:11 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( inline_array_rationals )
2016-03-03 18:48:42 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
ufixed128x3 [ 4 ] memory a = [ ufixed128x3 ( 3.5 ) , 4.125 , 2.5 , 4.0 ] ;
2016-03-03 18:48:42 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-03-03 18:48:42 +00:00
}
2016-05-10 08:46:25 +00:00
BOOST_AUTO_TEST_CASE ( rational_index_access )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-10 08:46:25 +00:00
uint [ ] memory a ;
a [ .5 ] ;
}
}
) " ;
2018-02-13 10:43:47 +00:00
CHECK_ERROR ( text , TypeError , " rational_const 1 / 2 is not implicitly convertible to expected type uint256 " ) ;
2016-05-10 08:46:25 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( rational_to_fixed_literal_expression )
2016-03-18 20:03:26 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
ufixed64x8 a = 3.5 * 3 ;
ufixed64x8 b = 4 - 2.5 ;
ufixed64x8 c = 11 / 4 ;
2016-12-22 18:20:03 +00:00
ufixed240x5 d = 599 + 0.21875 ;
ufixed256x80 e = ufixed256x80 ( 35.245 % 12.9 ) ;
ufixed256x80 f = ufixed256x80 ( 1.2 % 2 ) ;
2016-05-05 22:47:08 +00:00
fixed g = 2 * * - 2 ;
2017-04-14 14:48:59 +00:00
a ; b ; c ; d ; e ; f ; g ;
2016-03-18 20:03:26 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-03-18 20:03:26 +00:00
}
2016-12-22 18:20:03 +00:00
BOOST_AUTO_TEST_CASE ( rational_as_exponent_value_signed )
2016-03-18 20:03:26 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-05 22:47:08 +00:00
fixed g = 2 * * - 2.2 ;
2016-12-05 14:40:35 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " not compatible with types " ) ;
2016-12-05 14:40:35 +00:00
}
2016-12-22 18:20:03 +00:00
BOOST_AUTO_TEST_CASE ( rational_as_exponent_value_unsigned )
2016-12-05 14:40:35 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-05 22:47:08 +00:00
ufixed b = 3 * * 2.5 ;
2016-12-05 14:40:35 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " not compatible with types " ) ;
2016-12-05 14:40:35 +00:00
}
BOOST_AUTO_TEST_CASE ( rational_as_exponent_half )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
2 * * ( 1 / 2 ) ;
2016-12-05 14:40:35 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " not compatible with types " ) ;
2016-12-05 14:40:35 +00:00
}
BOOST_AUTO_TEST_CASE ( rational_as_exponent_value_neg_quarter )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
42 * * ( - 1 / 4 ) ;
2016-03-18 20:03:26 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " not compatible with types " ) ;
2016-03-18 20:03:26 +00:00
}
2016-12-05 14:40:35 +00:00
BOOST_AUTO_TEST_CASE ( fixed_point_casting_exponents_15 )
2016-04-08 06:19:20 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
var a = 3 * * ufixed ( 1.5 ) ;
2016-12-05 14:40:35 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " not compatible with types " ) ;
2016-12-05 14:40:35 +00:00
}
BOOST_AUTO_TEST_CASE ( fixed_point_casting_exponents_neg )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
var c = 42 * * fixed ( - 1 / 4 ) ;
2016-04-08 06:19:20 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " not compatible with types " ) ;
2016-04-08 06:19:20 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( var_capable_of_holding_constant_rationals )
2016-04-08 06:19:20 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-05 22:47:08 +00:00
var a = 0.12345678 ;
var b = 12345678.352 ;
var c = 0.00000009 ;
2017-04-14 14:48:59 +00:00
a ; b ; c ;
2016-04-08 06:19:20 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-04-08 06:19:20 +00:00
}
2016-05-10 08:46:25 +00:00
BOOST_AUTO_TEST_CASE ( var_and_rational_with_tuple )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-10 08:46:25 +00:00
var ( a , b ) = ( .5 , 1 / 3 ) ;
2017-04-14 14:48:59 +00:00
a ; b ;
2016-05-10 08:46:25 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-05-10 08:46:25 +00:00
}
2016-05-05 22:47:08 +00:00
BOOST_AUTO_TEST_CASE ( var_handle_divided_integers )
2016-03-18 20:03:26 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-05 22:47:08 +00:00
var x = 1 / 3 ;
2016-03-18 20:03:26 +00:00
}
}
) " ;
2017-02-05 19:06:04 +00:00
CHECK_SUCCESS ( text ) ;
2016-03-18 20:03:26 +00:00
}
BOOST_AUTO_TEST_CASE ( rational_bitnot_unary_operation )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
~ fixed ( 3.5 ) ;
2016-03-18 20:03:26 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " cannot be applied " ) ;
2016-03-18 20:03:26 +00:00
}
BOOST_AUTO_TEST_CASE ( rational_bitor_binary_operation )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
fixed ( 1.5 ) | 3 ;
2016-03-18 20:03:26 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " not compatible with types " ) ;
2016-03-18 20:03:26 +00:00
}
BOOST_AUTO_TEST_CASE ( rational_bitxor_binary_operation )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
fixed ( 1.75 ) ^ 3 ;
2016-03-18 20:03:26 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " not compatible with types " ) ;
2016-03-18 20:03:26 +00:00
}
BOOST_AUTO_TEST_CASE ( rational_bitand_binary_operation )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
fixed ( 1.75 ) & 3 ;
2016-03-18 20:03:26 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " not compatible with types " ) ;
2016-03-18 20:03:26 +00:00
}
2016-03-11 23:53:54 +00:00
2016-05-20 14:44:03 +00:00
BOOST_AUTO_TEST_CASE ( missing_bool_conversion )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function b ( uint a ) public {
2016-05-20 14:44:03 +00:00
bool ( a = = 1 ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-05-20 14:44:03 +00:00
}
2016-05-13 03:10:49 +00:00
BOOST_AUTO_TEST_CASE ( integer_and_fixed_interaction )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-12 13:44:27 +00:00
ufixed a = uint64 ( 1 ) + ufixed ( 2 ) ;
2016-05-13 03:10:49 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-05-13 03:10:49 +00:00
}
BOOST_AUTO_TEST_CASE ( one_divided_by_three_integer_conversion )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-05-13 03:10:49 +00:00
uint a = 1 / 3 ;
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " is not implicitly convertible to expected type uint256. Try converting to type ufixed256x77 " ) ;
2016-05-13 03:10:49 +00:00
}
2016-06-21 12:36:23 +00:00
BOOST_AUTO_TEST_CASE ( unused_return_value )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function g ( ) public returns ( uint ) { }
function f ( ) public {
2016-06-21 12:36:23 +00:00
g ( ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-06-21 12:36:23 +00:00
}
BOOST_AUTO_TEST_CASE ( unused_return_value_send )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-06-21 12:36:23 +00:00
address ( 0x12 ) . send ( 1 ) ;
}
}
) " ;
2017-03-15 10:10:24 +00:00
CHECK_WARNING ( text , " Failure condition of 'send' ignored. Consider using 'transfer' instead. " ) ;
2016-06-21 12:36:23 +00:00
}
2016-06-24 14:41:17 +00:00
BOOST_AUTO_TEST_CASE ( unused_return_value_call )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-06-24 14:41:17 +00:00
address ( 0x12 ) . call ( " abc " ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_WARNING ( text , " Return value of low-level calls not used " ) ;
2016-06-24 14:41:17 +00:00
}
BOOST_AUTO_TEST_CASE ( unused_return_value_call_value )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-06-24 14:41:17 +00:00
address ( 0x12 ) . call . value ( 2 ) ( " abc " ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_WARNING ( text , " Return value of low-level calls not used " ) ;
2016-06-24 14:41:17 +00:00
}
BOOST_AUTO_TEST_CASE ( unused_return_value_callcode )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-06-24 14:41:17 +00:00
address ( 0x12 ) . callcode ( " abc " ) ;
}
}
) " ;
2018-02-09 22:54:05 +00:00
CHECK_WARNING_ALLOW_MULTI ( text , ( std : : vector < std : : string > {
" Return value of low-level calls not used " ,
" \" callcode \" has been deprecated "
} ) ) ;
2016-06-24 14:41:17 +00:00
}
BOOST_AUTO_TEST_CASE ( unused_return_value_delegatecall )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-06-24 14:41:17 +00:00
address ( 0x12 ) . delegatecall ( " abc " ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_WARNING ( text , " Return value of low-level calls not used " ) ;
2016-06-24 14:41:17 +00:00
}
2017-06-30 14:37:08 +00:00
BOOST_AUTO_TEST_CASE ( warn_about_callcode )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2018-02-12 22:26:13 +00:00
address ( 0x12 ) . callcode ;
2017-06-30 14:37:08 +00:00
}
}
) " ;
2017-07-31 19:31:12 +00:00
CHECK_WARNING ( text , " \" callcode \" has been deprecated in favour of \" delegatecall \" " ) ;
2017-07-11 17:08:11 +00:00
text = R " (
pragma experimental " v0.5.0 " ;
contract test {
function f ( ) pure public {
2018-02-12 22:26:13 +00:00
address ( 0x12 ) . callcode ;
2017-07-11 17:08:11 +00:00
}
}
) " ;
CHECK_ERROR ( text , TypeError , " \" callcode \" has been deprecated in favour of \" delegatecall \" " ) ;
2017-06-30 14:37:08 +00:00
}
2017-08-30 22:27:25 +00:00
BOOST_AUTO_TEST_CASE ( no_warn_about_callcode_as_function )
2017-06-30 14:37:08 +00:00
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function callcode ( ) pure public {
2017-08-30 22:27:25 +00:00
test . callcode ( ) ;
2017-06-30 14:37:08 +00:00
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2016-08-26 18:37:10 +00:00
BOOST_AUTO_TEST_CASE ( payable_in_library )
{
char const * text = R " (
library test {
2017-09-05 15:11:53 +00:00
function f ( ) payable public { }
2016-08-26 18:37:10 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Library functions cannot be payable. " ) ;
2016-08-26 18:37:10 +00:00
}
2016-09-06 08:58:56 +00:00
BOOST_AUTO_TEST_CASE ( payable_external )
{
char const * text = R " (
contract test {
function f ( ) payable external { }
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-09-06 08:58:56 +00:00
}
2016-08-26 18:37:10 +00:00
BOOST_AUTO_TEST_CASE ( payable_internal )
{
char const * text = R " (
contract test {
function f ( ) payable internal { }
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Internal functions cannot be payable. " ) ;
2016-09-06 08:58:56 +00:00
}
BOOST_AUTO_TEST_CASE ( payable_private )
{
char const * text = R " (
contract test {
function f ( ) payable private { }
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Internal functions cannot be payable. " ) ;
2016-08-26 18:37:10 +00:00
}
BOOST_AUTO_TEST_CASE ( illegal_override_payable )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract B { function f ( ) payable public { } }
contract C is B { function f ( ) public { } }
2016-08-26 18:37:10 +00:00
) " ;
2017-08-15 23:29:59 +00:00
CHECK_ERROR ( text , TypeError , " Overriding function changes state mutability from \" payable \" to \" nonpayable \" . " ) ;
2016-08-26 18:37:10 +00:00
}
BOOST_AUTO_TEST_CASE ( illegal_override_payable_nonpayable )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract B { function f ( ) public { } }
contract C is B { function f ( ) payable public { } }
2016-08-26 18:37:10 +00:00
) " ;
2017-08-15 23:29:59 +00:00
CHECK_ERROR ( text , TypeError , " Overriding function changes state mutability from \" nonpayable \" to \" payable \" . " ) ;
2016-08-26 18:37:10 +00:00
}
2016-12-02 15:06:01 +00:00
BOOST_AUTO_TEST_CASE ( function_variable_mixin )
{
// bug #1798 (cpp-ethereum), related to #1286 (solidity)
char const * text = R " (
contract attribute {
bool ok = false ;
}
contract func {
2017-09-05 15:11:53 +00:00
function ok ( ) public returns ( bool ) { return true ; }
2016-12-02 15:06:01 +00:00
}
contract attr_func is attribute , func {
2017-09-05 15:11:53 +00:00
function checkOk ( ) public returns ( bool ) { return ok ( ) ; }
2016-12-02 15:06:01 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , DeclarationError , " Identifier already declared. " ) ;
2016-12-02 15:06:01 +00:00
}
2016-08-26 18:37:10 +00:00
BOOST_AUTO_TEST_CASE ( calling_payable )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract receiver { function pay ( ) payable public { } }
2016-08-26 18:37:10 +00:00
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public { ( new receiver ( ) ) . pay . value ( 10 ) ( ) ; }
2016-11-08 16:09:24 +00:00
receiver r = new receiver ( ) ;
2017-09-05 15:11:53 +00:00
function g ( ) public { r . pay . value ( 10 ) ( ) ; }
2016-08-26 18:37:10 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-08-26 18:37:10 +00:00
}
BOOST_AUTO_TEST_CASE ( calling_nonpayable )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract receiver { function nopay ( ) public { } }
2016-08-26 18:37:10 +00:00
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public { ( new receiver ( ) ) . nopay . value ( 10 ) ( ) ; }
2016-08-31 18:43:24 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" value \" not found or not visible after argument-dependent lookup in function () external - did you forget the \" payable \" modifier? " ) ;
2016-08-31 18:43:24 +00:00
}
BOOST_AUTO_TEST_CASE ( non_payable_constructor )
{
char const * text = R " (
contract C {
function C ( ) { }
}
contract D {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( uint ) {
2016-08-31 18:43:24 +00:00
( new C ) . value ( 2 ) ( ) ;
return 2 ;
}
2016-08-26 18:37:10 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" value \" not found or not visible after argument-dependent lookup in function () returns (contract C) - did you forget the \" payable \" modifier? " ) ;
2016-08-06 13:08:06 +00:00
}
2016-08-19 17:57:21 +00:00
BOOST_AUTO_TEST_CASE ( warn_nonpresent_pragma )
{
char const * text = " contract C {} " ;
auto sourceAndError = parseAnalyseAndReturnError ( text , true , false ) ;
2018-02-09 22:54:05 +00:00
BOOST_REQUIRE ( ! sourceAndError . second . empty ( ) ) ;
2016-08-19 17:57:21 +00:00
BOOST_REQUIRE ( ! ! sourceAndError . first ) ;
2018-02-09 22:54:05 +00:00
BOOST_CHECK ( searchErrorMessage ( * sourceAndError . second . front ( ) , " Source file does not specify required compiler version! " ) ) ;
2016-08-19 17:57:21 +00:00
}
BOOST_AUTO_TEST_CASE ( unsatisfied_version )
{
char const * text = R " (
pragma solidity ^ 99.99 .0 ;
) " ;
2017-08-28 18:40:38 +00:00
auto sourceAndError = parseAnalyseAndReturnError ( text , false , false , false ) ;
2018-02-09 22:54:05 +00:00
BOOST_REQUIRE ( ! sourceAndError . second . empty ( ) ) ;
2017-08-28 18:40:38 +00:00
BOOST_REQUIRE ( ! ! sourceAndError . first ) ;
2018-02-09 22:54:05 +00:00
BOOST_CHECK ( sourceAndError . second . front ( ) - > type ( ) = = Error : : Type : : SyntaxError ) ;
BOOST_CHECK ( searchErrorMessage ( * sourceAndError . second . front ( ) , " Source file requires different compiler version " ) ) ;
2016-08-19 17:57:21 +00:00
}
2017-09-05 15:11:53 +00:00
BOOST_AUTO_TEST_CASE ( invalid_constructor_statemutability )
2016-09-06 01:51:01 +00:00
{
char const * text = R " (
contract test {
function test ( ) constant { }
}
) " ;
2017-08-15 23:28:13 +00:00
CHECK_ERROR ( text , TypeError , " Constructor must be payable or non-payable " ) ;
2017-09-05 15:11:53 +00:00
text = R " (
contract test {
function test ( ) view { }
}
) " ;
CHECK_ERROR ( text , TypeError , " Constructor must be payable or non-payable " ) ;
text = R " (
contract test {
function test ( ) pure { }
}
) " ;
CHECK_ERROR ( text , TypeError , " Constructor must be payable or non-payable " ) ;
2016-09-06 01:51:01 +00:00
}
2016-09-06 03:20:57 +00:00
BOOST_AUTO_TEST_CASE ( external_constructor )
{
char const * text = R " (
contract test {
function test ( ) external { }
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Constructor must be public or internal. " ) ;
2016-09-06 03:20:57 +00:00
}
2016-09-15 16:01:13 +00:00
BOOST_AUTO_TEST_CASE ( invalid_array_as_statement )
{
char const * text = R " (
contract test {
struct S { uint x ; }
2017-09-05 15:11:53 +00:00
function test ( uint k ) public { S [ k ] ; }
2016-09-15 16:01:13 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Integer constant expected. " ) ;
2016-09-15 16:01:13 +00:00
}
2016-09-06 01:51:01 +00:00
2016-10-14 18:28:15 +00:00
BOOST_AUTO_TEST_CASE ( using_directive_for_missing_selftype )
{
char const * text = R " (
library B {
2017-09-05 15:11:53 +00:00
function b ( ) public { }
2016-10-14 18:28:15 +00:00
}
contract A {
using B for bytes ;
2017-09-05 15:11:53 +00:00
function a ( ) public {
2016-10-14 18:28:15 +00:00
bytes memory x ;
x . b ( ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" b \" not found or not visible after argument-dependent lookup in bytes memory " ) ;
2016-10-14 18:28:15 +00:00
}
2016-09-06 23:16:49 +00:00
BOOST_AUTO_TEST_CASE ( shift_constant_left_negative_rvalue )
{
char const * text = R " (
contract C {
uint public a = 0x42 < < - 8 ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Operator << not compatible with types int_const 66 and int_const -8 " ) ;
2016-09-06 23:16:49 +00:00
}
BOOST_AUTO_TEST_CASE ( shift_constant_right_negative_rvalue )
{
char const * text = R " (
contract C {
uint public a = 0x42 > > - 8 ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Operator >> not compatible with types int_const 66 and int_const -8 " ) ;
2016-09-06 23:16:49 +00:00
}
BOOST_AUTO_TEST_CASE ( shift_constant_left_excessive_rvalue )
{
char const * text = R " (
contract C {
uint public a = 0x42 < < 0x100000000 ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Operator << not compatible with types int_const 66 and int_const 4294967296 " ) ;
2016-09-06 23:16:49 +00:00
}
BOOST_AUTO_TEST_CASE ( shift_constant_right_excessive_rvalue )
{
char const * text = R " (
contract C {
uint public a = 0x42 > > 0x100000000 ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Operator >> not compatible with types int_const 66 and int_const 4294967296 " ) ;
2016-09-06 23:16:49 +00:00
}
2018-03-22 04:20:50 +00:00
BOOST_AUTO_TEST_CASE ( shift_constant_right_fractional )
{
char const * text = R " (
contract C {
uint public a = 0x42 > > ( 1 / 2 ) ;
}
) " ;
CHECK_ERROR ( text , TypeError , " Operator >> not compatible with types int_const 66 and rational_const 1 / 2 " ) ;
}
2016-10-20 00:15:39 +00:00
BOOST_AUTO_TEST_CASE ( inline_assembly_unbalanced_positive_stack )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-10-20 00:15:39 +00:00
assembly {
1
}
}
}
) " ;
2017-03-22 12:21:41 +00:00
CHECK_ERROR ( text , DeclarationError , " Unbalanced stack at the end of a block: 1 surplus item(s). " ) ;
2016-10-20 00:15:39 +00:00
}
BOOST_AUTO_TEST_CASE ( inline_assembly_unbalanced_negative_stack )
{
char const * text = R " (
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-10-20 00:15:39 +00:00
assembly {
pop
}
}
}
) " ;
2017-03-22 12:21:41 +00:00
CHECK_ERROR ( text , DeclarationError , " Unbalanced stack at the end of a block: 1 missing item(s). " ) ;
2016-10-20 00:15:39 +00:00
}
2017-02-20 11:32:31 +00:00
BOOST_AUTO_TEST_CASE ( inline_assembly_unbalanced_two_stack_load )
{
char const * text = R " (
2018-02-15 16:25:54 +00:00
pragma experimental " v0.5.0 " ;
2017-02-20 11:32:31 +00:00
contract c {
uint8 x ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2018-02-15 16:25:54 +00:00
assembly { pop ( x ) }
2017-02-20 11:32:31 +00:00
}
}
) " ;
2017-04-25 11:15:42 +00:00
CHECK_ERROR ( text , TypeError , " Only local variables are supported. To access storage variables, " ) ;
2017-02-20 11:32:31 +00:00
}
2016-10-20 22:36:05 +00:00
BOOST_AUTO_TEST_CASE ( inline_assembly_in_modifier )
{
char const * text = R " (
2018-02-15 16:25:54 +00:00
pragma experimental " v0.5.0 " ;
2016-10-20 22:36:05 +00:00
contract test {
modifier m {
uint a = 1 ;
assembly {
2016-10-21 10:30:48 +00:00
a : = 2
2016-10-20 22:36:05 +00:00
}
_ ;
}
2018-02-15 16:25:54 +00:00
function f ( ) public m {
2016-10-20 22:36:05 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-10-20 22:36:05 +00:00
}
BOOST_AUTO_TEST_CASE ( inline_assembly_storage )
{
char const * text = R " (
2018-02-15 16:25:54 +00:00
pragma experimental " v0.5.0 " ;
2016-10-20 22:36:05 +00:00
contract test {
uint x = 1 ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-10-20 22:36:05 +00:00
assembly {
2016-10-21 10:30:48 +00:00
x : = 2
2016-10-20 22:36:05 +00:00
}
}
}
) " ;
2017-04-25 11:15:42 +00:00
CHECK_ERROR ( text , TypeError , " Only local variables are supported. To access storage variables, " ) ;
2016-10-20 22:36:05 +00:00
}
BOOST_AUTO_TEST_CASE ( inline_assembly_storage_in_modifiers )
{
char const * text = R " (
2018-02-15 16:25:54 +00:00
pragma experimental " v0.5.0 " ;
2016-10-20 22:36:05 +00:00
contract test {
uint x = 1 ;
modifier m {
assembly {
2016-10-21 10:30:48 +00:00
x : = 2
2016-10-20 22:36:05 +00:00
}
_ ;
}
2018-02-15 16:25:54 +00:00
function f ( ) public m {
2016-10-20 22:36:05 +00:00
}
}
) " ;
2017-04-25 11:15:42 +00:00
CHECK_ERROR ( text , TypeError , " Only local variables are supported. To access storage variables, " ) ;
2016-10-20 22:36:05 +00:00
}
2017-04-11 17:24:38 +00:00
BOOST_AUTO_TEST_CASE ( inline_assembly_constant_assign )
{
char const * text = R " (
2018-02-15 16:25:54 +00:00
pragma experimental " v0.5.0 " ;
2017-04-11 17:24:38 +00:00
contract test {
uint constant x = 1 ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-04-11 17:24:38 +00:00
assembly {
x : = 2
}
}
}
) " ;
2017-04-25 11:15:42 +00:00
CHECK_ERROR ( text , TypeError , " Constant variables not supported by inline assembly " ) ;
2017-04-11 17:24:38 +00:00
}
BOOST_AUTO_TEST_CASE ( inline_assembly_constant_access )
{
char const * text = R " (
2018-02-15 16:25:54 +00:00
pragma experimental " v0.5.0 " ;
2017-04-11 17:24:38 +00:00
contract test {
uint constant x = 1 ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-04-11 17:24:38 +00:00
assembly {
let y : = x
}
}
}
) " ;
2017-04-25 11:15:42 +00:00
CHECK_ERROR ( text , TypeError , " Constant variables not supported by inline assembly " ) ;
2017-04-11 17:24:38 +00:00
}
2017-05-29 18:32:47 +00:00
BOOST_AUTO_TEST_CASE ( inline_assembly_local_variable_access_out_of_functions )
2017-05-24 16:34:19 +00:00
{
char const * text = R " (
2018-02-15 16:25:54 +00:00
pragma experimental " v0.5.0 " ;
2017-05-24 16:34:19 +00:00
contract test {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-05-24 16:34:19 +00:00
uint a ;
assembly {
function g ( ) - > x { x : = a }
}
}
}
) " ;
2017-05-29 18:32:47 +00:00
CHECK_ERROR ( text , DeclarationError , " Cannot access local Solidity variables from inside an inline assembly function. " ) ;
}
BOOST_AUTO_TEST_CASE ( inline_assembly_local_variable_access_out_of_functions_storage_ptr )
{
char const * text = R " (
2018-02-15 16:25:54 +00:00
pragma experimental " v0.5.0 " ;
2017-05-29 18:32:47 +00:00
contract test {
uint [ ] r ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-05-29 18:32:47 +00:00
uint [ ] storage a = r ;
assembly {
function g ( ) - > x { x : = a_offset }
}
}
}
) " ;
CHECK_ERROR ( text , DeclarationError , " Cannot access local Solidity variables from inside an inline assembly function. " ) ;
}
BOOST_AUTO_TEST_CASE ( inline_assembly_storage_variable_access_out_of_functions )
{
char const * text = R " (
2018-02-15 16:25:54 +00:00
pragma experimental " v0.5.0 " ;
2017-05-29 18:32:47 +00:00
contract test {
uint a ;
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-05-29 18:32:47 +00:00
assembly {
function g ( ) - > x { x : = a_slot }
}
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2017-05-24 16:34:19 +00:00
}
2018-02-19 18:21:16 +00:00
BOOST_AUTO_TEST_CASE ( inline_assembly_constant_variable_via_offset )
{
char const * text = R " (
contract test {
uint constant x = 2 ;
function f ( ) pure public {
assembly {
let r : = x_offset
}
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Constant variables not supported by inline assembly. " ) ;
}
2017-07-11 11:37:34 +00:00
BOOST_AUTO_TEST_CASE ( inline_assembly_calldata_variables )
{
char const * text = R " (
2018-02-15 16:25:54 +00:00
pragma experimental " v0.5.0 " ;
2017-07-11 11:37:34 +00:00
contract C {
function f ( bytes bytesAsCalldata ) external {
assembly {
let x : = bytesAsCalldata
}
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Call data elements cannot be accessed directly. " ) ;
}
2018-02-15 16:25:54 +00:00
BOOST_AUTO_TEST_CASE ( inline_assembly_050_literals_on_stack )
{
char const * text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function f ( ) pure public {
assembly {
1
}
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : SyntaxError , " are not supposed to return " } ,
{ Error : : Type : : DeclarationError , " Unbalanced stack " } ,
} ) ) ;
}
BOOST_AUTO_TEST_CASE ( inline_assembly_literals_on_stack )
{
char const * text = R " (
contract C {
function f ( ) pure public {
assembly {
1
}
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : Warning , " are not supposed to return " } ,
{ Error : : Type : : DeclarationError , " Unbalanced stack " } ,
} ) ) ;
}
BOOST_AUTO_TEST_CASE ( inline_assembly_050_bare_instructions )
{
char const * text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function f ( ) view public {
assembly {
address
pop
}
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : SyntaxError , " The use of non-functional " } ,
{ Error : : Type : : SyntaxError , " The use of non-functional " }
} ) ) ;
}
BOOST_AUTO_TEST_CASE ( inline_assembly_bare_instructions )
{
char const * text = R " (
contract C {
function f ( ) view public {
assembly {
address
pop
}
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : Warning , " The use of non-functional " } ,
{ Error : : Type : : Warning , " The use of non-functional " }
} ) ) ;
}
BOOST_AUTO_TEST_CASE ( inline_assembly_050_labels )
{
char const * text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function f ( ) pure public {
assembly {
label :
}
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : SyntaxError , " Jump instructions and labels are low-level " } ,
{ Error : : Type : : SyntaxError , " The use of labels is deprecated " }
} ) ) ;
}
BOOST_AUTO_TEST_CASE ( inline_assembly_labels )
{
char const * text = R " (
contract C {
function f ( ) pure public {
assembly {
label :
}
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : Warning , " Jump instructions and labels are low-level " } ,
{ Error : : Type : : Warning , " The use of labels is deprecated " }
} ) ) ;
}
BOOST_AUTO_TEST_CASE ( inline_assembly_050_jump )
{
char const * text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function f ( ) pure public {
assembly {
jump ( 2 )
}
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : SyntaxError , " Jump instructions and labels are low-level " }
} ) ) ;
}
BOOST_AUTO_TEST_CASE ( inline_assembly_jump )
{
char const * text = R " (
contract C {
function f ( ) pure public {
assembly {
jump ( 2 )
}
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : TypeError , " Function declared as pure " } ,
{ Error : : Type : : Warning , " Jump instructions and labels are low-level " }
} ) ) ;
}
BOOST_AUTO_TEST_CASE ( inline_assembly_050_leave_items_on_stack )
{
char const * text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function f ( ) pure public {
assembly {
mload ( 0 )
}
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : SyntaxError , " are not supposed to return " } ,
{ Error : : Type : : DeclarationError , " Unbalanced stack " } ,
} ) ) ;
}
BOOST_AUTO_TEST_CASE ( inline_assembly_leave_items_on_stack )
{
char const * text = R " (
contract C {
function f ( ) pure public {
assembly {
mload ( 0 )
}
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : Warning , " are not supposed to return " } ,
{ Error : : Type : : DeclarationError , " Unbalanced stack " } ,
} ) ) ;
}
2016-10-21 10:30:48 +00:00
BOOST_AUTO_TEST_CASE ( invalid_mobile_type )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2016-10-21 10:30:48 +00:00
// Invalid number
[ 1 , 78901234567890123456789012345678901234567890123456789345678901234567890012345678012345678901234567 ] ;
}
}
) " ;
2017-09-18 10:39:17 +00:00
CHECK_ERROR ( text , TypeError , " Invalid rational number. " ) ;
2016-10-21 10:30:48 +00:00
}
2016-12-01 13:55:02 +00:00
BOOST_AUTO_TEST_CASE ( warns_msg_value_in_non_payable_public_function )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) view public {
2016-12-01 13:55:02 +00:00
msg . value ;
}
}
) " ;
CHECK_WARNING ( text , " \" msg.value \" used in non-payable function. Do you want to add the \" payable \" modifier to this function? " ) ;
}
BOOST_AUTO_TEST_CASE ( does_not_warn_msg_value_in_payable_function )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) payable public {
2016-12-01 13:55:02 +00:00
msg . value ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( does_not_warn_msg_value_in_internal_function )
{
char const * text = R " (
contract C {
2016-11-18 03:14:13 +00:00
function f ( ) view internal {
2016-12-01 13:55:02 +00:00
msg . value ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( does_not_warn_msg_value_in_library )
{
char const * text = R " (
library C {
2017-09-05 15:11:53 +00:00
function f ( ) view public {
2016-12-01 13:55:02 +00:00
msg . value ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( does_not_warn_msg_value_in_modifier_following_non_payable_public_function )
{
char const * text = R " (
contract c {
2017-09-05 15:11:53 +00:00
function f ( ) pure public { }
2016-12-01 13:55:02 +00:00
modifier m ( ) { msg . value ; _ ; }
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2016-12-13 02:59:53 +00:00
BOOST_AUTO_TEST_CASE ( assignment_to_constant )
{
char const * text = R " (
contract c {
uint constant a = 1 ;
2017-09-05 15:11:53 +00:00
function f ( ) public { a = 2 ; }
2016-12-13 02:59:53 +00:00
}
) " ;
CHECK_ERROR ( text , TypeError , " Cannot assign to a constant variable. " ) ;
}
2017-01-20 18:11:22 +00:00
BOOST_AUTO_TEST_CASE ( inconstructible_internal_constructor )
{
char const * text = R " (
contract C {
function C ( ) internal { }
}
contract D {
2017-09-05 15:11:53 +00:00
function f ( ) public { var x = new C ( ) ; }
2017-01-20 18:11:22 +00:00
}
) " ;
CHECK_ERROR ( text , TypeError , " Contract with internal constructor cannot be created directly. " ) ;
}
2017-03-06 13:11:55 +00:00
BOOST_AUTO_TEST_CASE ( inconstructible_internal_constructor_inverted )
{
// Previously, the type information for A was not yet available at the point of
// "new A".
char const * text = R " (
contract B {
A a ;
2017-09-05 15:11:53 +00:00
function B ( ) public {
2017-03-06 13:11:55 +00:00
a = new A ( this ) ;
}
}
contract A {
function A ( address a ) internal { }
}
) " ;
CHECK_ERROR ( text , TypeError , " Contract with internal constructor cannot be created directly. " ) ;
}
2017-01-20 18:11:22 +00:00
BOOST_AUTO_TEST_CASE ( constructible_internal_constructor )
{
char const * text = R " (
contract C {
function C ( ) internal { }
}
contract D is C {
2017-09-05 15:11:53 +00:00
function D ( ) public { }
2017-01-20 18:11:22 +00:00
}
) " ;
2017-11-22 14:06:12 +00:00
CHECK_SUCCESS ( text ) ;
2017-01-20 18:11:22 +00:00
}
2017-01-24 11:44:49 +00:00
BOOST_AUTO_TEST_CASE ( return_structs )
{
char const * text = R " (
2017-12-11 02:39:39 +00:00
pragma experimental ABIEncoderV2 ;
2017-01-24 11:44:49 +00:00
contract C {
struct S { uint a ; T [ ] sub ; }
struct T { uint [ ] x ; }
2017-06-01 10:26:13 +00:00
function f ( ) returns ( uint , S ) {
2017-01-24 11:44:49 +00:00
}
}
) " ;
2017-11-22 14:06:12 +00:00
CHECK_SUCCESS ( text ) ;
2017-01-24 11:44:49 +00:00
}
2018-02-21 14:59:34 +00:00
BOOST_AUTO_TEST_CASE ( read_returned_struct )
{
char const * text = R " (
pragma experimental ABIEncoderV2 ;
contract A {
struct T {
int x ;
int y ;
}
function g ( ) public returns ( T ) {
return this . g ( ) ;
}
}
) " ;
CHECK_WARNING ( text , " Experimental features " ) ;
}
2017-01-24 16:38:06 +00:00
BOOST_AUTO_TEST_CASE ( address_checksum_type_deduction )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-01-24 16:38:06 +00:00
var x = 0xfA0bFc97E48458494Ccd857e1A85DC91F7F0046E ;
x . send ( 2 ) ;
}
}
) " ;
2017-11-22 14:06:12 +00:00
CHECK_SUCCESS ( text ) ;
2017-01-24 16:38:06 +00:00
}
BOOST_AUTO_TEST_CASE ( invalid_address_checksum )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-06-22 14:54:24 +00:00
address x = 0xFA0bFc97E48458494Ccd857e1A85DC91F7F0046E ;
2017-04-14 14:48:59 +00:00
x ;
2017-01-24 16:38:06 +00:00
}
}
) " ;
2017-10-24 10:55:30 +00:00
CHECK_WARNING ( text , " This looks like an address but has an invalid checksum. " ) ;
2017-01-24 16:38:06 +00:00
}
BOOST_AUTO_TEST_CASE ( invalid_address_no_checksum )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-06-22 14:54:24 +00:00
address x = 0xfa0bfc97e48458494ccd857e1a85dc91f7f0046e ;
2017-04-14 14:48:59 +00:00
x ;
2017-01-24 16:38:06 +00:00
}
}
) " ;
2017-10-24 10:55:30 +00:00
CHECK_WARNING ( text , " This looks like an address but has an invalid checksum. " ) ;
2017-01-24 16:38:06 +00:00
}
2017-10-24 10:55:30 +00:00
BOOST_AUTO_TEST_CASE ( invalid_address_length_short )
2017-01-24 16:38:06 +00:00
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-06-22 14:54:24 +00:00
address x = 0xA0bFc97E48458494Ccd857e1A85DC91F7F0046E ;
2017-04-14 14:48:59 +00:00
x ;
2017-01-24 16:38:06 +00:00
}
}
) " ;
2017-10-24 10:55:30 +00:00
CHECK_WARNING ( text , " This looks like an address but has an invalid checksum. " ) ;
}
BOOST_AUTO_TEST_CASE ( invalid_address_length_long )
{
char const * text = R " (
contract C {
function f ( ) pure public {
address x = 0xFA0bFc97E48458494Ccd857e1A85DC91F7F0046E0 ;
x ;
}
}
) " ;
2018-02-09 22:54:05 +00:00
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : Warning , " This looks like an address but has an invalid checksum. " } ,
{ Error : : Type : : TypeError , " not implicitly convertible " }
} ) ) ;
2017-01-24 16:38:06 +00:00
}
2017-06-22 14:42:35 +00:00
BOOST_AUTO_TEST_CASE ( address_test_for_bug_in_implementation )
{
// A previous implementation claimed the string would be an address
char const * text = R " (
contract AddrString {
address public test = " 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c " ;
}
) " ;
CHECK_ERROR ( text , TypeError , " is not implicitly convertible to expected type address " ) ;
text = R " (
contract AddrString {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( address ) {
2017-06-22 14:42:35 +00:00
return " 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c " ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " is not implicitly convertible to expected type " ) ;
}
2017-02-16 13:54:17 +00:00
BOOST_AUTO_TEST_CASE ( early_exit_on_fatal_errors )
{
// This tests a crash that occured because we did not stop for fatal errors.
char const * text = R " (
contract C {
struct S {
ftring a ;
}
S public s ;
function s ( ) s {
}
}
) " ;
CHECK_ERROR ( text , DeclarationError , " Identifier not found or not unique " ) ;
}
2017-02-06 16:14:43 +00:00
BOOST_AUTO_TEST_CASE ( address_methods )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-02-06 16:14:43 +00:00
address addr ;
uint balance = addr . balance ;
bool callRet = addr . call ( ) ;
bool callcodeRet = addr . callcode ( ) ;
bool delegatecallRet = addr . delegatecall ( ) ;
bool sendRet = addr . send ( 1 ) ;
addr . transfer ( 1 ) ;
2017-04-14 14:48:59 +00:00
callRet ; callcodeRet ; delegatecallRet ; sendRet ;
2017-02-06 16:14:43 +00:00
}
}
) " ;
CHECK_SUCCESS ( text ) ;
}
2017-02-11 21:17:24 +00:00
BOOST_AUTO_TEST_CASE ( interface )
{
char const * text = R " (
interface I {
}
) " ;
2017-11-22 14:06:12 +00:00
CHECK_SUCCESS ( text ) ;
2017-02-11 21:17:24 +00:00
}
BOOST_AUTO_TEST_CASE ( interface_constructor )
{
char const * text = R " (
interface I {
function I ( ) ;
}
) " ;
2018-02-09 22:54:05 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , ( std : : vector < std : : string > {
" Constructor cannot be defined in interfaces " ,
" Constructor must be implemented if declared. " ,
} ) ) ;
2017-02-11 21:17:24 +00:00
}
BOOST_AUTO_TEST_CASE ( interface_functions )
{
char const * text = R " (
interface I {
function ( ) ;
function f ( ) ;
}
) " ;
2017-11-22 14:06:12 +00:00
CHECK_SUCCESS ( text ) ;
2017-02-11 21:17:24 +00:00
}
BOOST_AUTO_TEST_CASE ( interface_function_bodies )
{
char const * text = R " (
interface I {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-02-11 21:17:24 +00:00
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Functions in interfaces cannot have an implementation " ) ;
}
BOOST_AUTO_TEST_CASE ( interface_events )
{
char const * text = R " (
interface I {
event E ( ) ;
}
) " ;
2017-11-22 14:06:12 +00:00
CHECK_SUCCESS ( text ) ;
2017-02-11 21:17:24 +00:00
}
BOOST_AUTO_TEST_CASE ( interface_inheritance )
{
char const * text = R " (
interface A {
}
interface I is A {
}
) " ;
CHECK_ERROR ( text , TypeError , " Interfaces cannot inherit " ) ;
}
BOOST_AUTO_TEST_CASE ( interface_structs )
{
char const * text = R " (
interface I {
struct A {
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Structs cannot be defined in interfaces " ) ;
}
BOOST_AUTO_TEST_CASE ( interface_variables )
{
char const * text = R " (
interface I {
uint a ;
}
) " ;
2017-02-15 11:43:26 +00:00
CHECK_ERROR ( text , TypeError , " Variables cannot be declared in interfaces " ) ;
2017-02-11 21:17:24 +00:00
}
2017-06-15 15:36:14 +00:00
BOOST_AUTO_TEST_CASE ( interface_function_parameters )
{
char const * text = R " (
interface I {
2017-09-05 15:11:53 +00:00
function f ( uint a ) public returns ( bool ) ;
2017-06-15 15:36:14 +00:00
}
) " ;
2017-11-22 14:06:12 +00:00
CHECK_SUCCESS ( text ) ;
2017-06-15 15:36:14 +00:00
}
2017-03-15 22:12:31 +00:00
BOOST_AUTO_TEST_CASE ( interface_enums )
{
char const * text = R " (
interface I {
enum A { B , C }
}
) " ;
CHECK_ERROR ( text , TypeError , " Enumerable cannot be declared in interfaces " ) ;
}
2017-02-11 21:17:24 +00:00
BOOST_AUTO_TEST_CASE ( using_interface )
{
char const * text = R " (
interface I {
function f ( ) ;
}
contract C is I {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-02-11 21:17:24 +00:00
}
}
) " ;
2017-11-22 14:06:12 +00:00
CHECK_SUCCESS ( text ) ;
2017-02-11 21:17:24 +00:00
}
2017-03-17 16:55:13 +00:00
BOOST_AUTO_TEST_CASE ( using_interface_complex )
{
char const * text = R " (
interface I {
event A ( ) ;
function f ( ) ;
function g ( ) ;
function ( ) ;
}
contract C is I {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-03-17 16:55:13 +00:00
}
}
) " ;
2017-11-22 14:06:12 +00:00
CHECK_SUCCESS ( text ) ;
2017-03-17 16:55:13 +00:00
}
2018-02-27 11:02:56 +00:00
BOOST_AUTO_TEST_CASE ( interface_implement_public_contract )
{
char const * text = R " (
interface I {
function f ( ) external ;
}
contract C is I {
function f ( ) public {
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2017-07-05 17:45:12 +00:00
BOOST_AUTO_TEST_CASE ( warn_about_throw )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-07-05 17:45:12 +00:00
throw ;
}
}
) " ;
2018-02-27 01:10:24 +00:00
CHECK_WARNING ( text , " \" throw \" is deprecated in favour of \" revert() \" , \" require() \" and \" assert() \" " ) ;
text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function f ( ) pure public {
throw ;
}
}
) " ;
CHECK_ERROR ( text , SyntaxError , " \" throw \" is deprecated in favour of \" revert() \" , \" require() \" and \" assert() \" " ) ;
2017-07-05 17:45:12 +00:00
}
2017-04-21 09:13:10 +00:00
BOOST_AUTO_TEST_CASE ( bare_revert )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( uint x ) pure public {
2017-04-21 09:13:10 +00:00
if ( x > 7 )
revert ;
}
}
) " ;
2017-12-30 12:48:07 +00:00
CHECK_ERROR ( text , TypeError , " No matching declaration found " ) ;
}
BOOST_AUTO_TEST_CASE ( revert_with_reason )
{
char const * text = R " (
contract C {
function f ( uint x ) pure public {
if ( x > 7 )
revert ( " abc " ) ;
else
revert ( ) ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2017-04-21 09:13:10 +00:00
}
2017-04-24 16:08:21 +00:00
BOOST_AUTO_TEST_CASE ( bare_others )
{
2017-09-05 15:11:53 +00:00
CHECK_WARNING ( " contract C { function f() pure public { selfdestruct; } } " , " Statement has no effect. " ) ;
CHECK_WARNING ( " contract C { function f() pure public { assert; } } " , " Statement has no effect. " ) ;
2018-01-04 16:08:47 +00:00
// This is different because it does have overloads.
CHECK_ERROR ( " contract C { function f() pure public { require; } } " , TypeError , " No matching declaration found after variable lookup. " ) ;
2017-09-05 15:11:53 +00:00
CHECK_WARNING ( " contract C { function f() pure public { suicide; } } " , " Statement has no effect. " ) ;
2017-04-24 16:08:21 +00:00
}
2017-04-21 09:13:10 +00:00
BOOST_AUTO_TEST_CASE ( pure_statement_in_for_loop )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-04-21 09:13:10 +00:00
for ( uint x = 0 ; x < 10 ; true )
x + + ;
}
}
) " ;
2017-04-21 13:04:03 +00:00
CHECK_WARNING ( text , " Statement has no effect. " ) ;
2017-04-21 09:13:10 +00:00
}
2017-04-21 18:09:37 +00:00
BOOST_AUTO_TEST_CASE ( pure_statement_check_for_regular_for_loop )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-04-21 18:09:37 +00:00
for ( uint x = 0 ; true ; x + + )
{ }
}
}
) " ;
2017-11-22 14:06:12 +00:00
CHECK_SUCCESS ( text ) ;
2017-04-21 18:09:37 +00:00
}
2017-06-21 17:32:56 +00:00
BOOST_AUTO_TEST_CASE ( warn_multiple_storage_storage_copies )
{
char const * text = R " (
contract C {
struct S { uint a ; uint b ; }
S x ; S y ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-06-21 17:32:56 +00:00
( x , y ) = ( y , x ) ;
}
}
) " ;
CHECK_WARNING ( text , " This assignment performs two copies to storage. " ) ;
}
BOOST_AUTO_TEST_CASE ( warn_multiple_storage_storage_copies_fill_right )
{
char const * text = R " (
contract C {
struct S { uint a ; uint b ; }
S x ; S y ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-06-21 17:32:56 +00:00
( x , y , ) = ( y , x , 1 , 2 ) ;
}
}
) " ;
CHECK_WARNING ( text , " This assignment performs two copies to storage. " ) ;
}
BOOST_AUTO_TEST_CASE ( warn_multiple_storage_storage_copies_fill_left )
{
char const * text = R " (
contract C {
struct S { uint a ; uint b ; }
S x ; S y ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-06-21 17:32:56 +00:00
( , x , y ) = ( 1 , 2 , y , x ) ;
}
}
) " ;
CHECK_WARNING ( text , " This assignment performs two copies to storage. " ) ;
}
2017-06-26 14:35:44 +00:00
BOOST_AUTO_TEST_CASE ( nowarn_swap_memory )
{
char const * text = R " (
contract C {
struct S { uint a ; uint b ; }
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-06-26 14:35:44 +00:00
S memory x ;
S memory y ;
( x , y ) = ( y , x ) ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( nowarn_swap_storage_pointers )
{
char const * text = R " (
contract C {
struct S { uint a ; uint b ; }
S x ; S y ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-06-26 14:35:44 +00:00
S storage x_local = x ;
S storage y_local = y ;
S storage z_local = x ;
( x , y_local , x_local , z_local ) = ( y , x_local , y_local , y ) ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2017-04-14 14:48:59 +00:00
BOOST_AUTO_TEST_CASE ( warn_unused_local )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-04-14 14:48:59 +00:00
uint a ;
}
}
) " ;
2017-08-29 15:58:38 +00:00
CHECK_WARNING ( text , " Unused local variable. " ) ;
2017-04-14 14:48:59 +00:00
}
BOOST_AUTO_TEST_CASE ( warn_unused_local_assigned )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-06-22 14:54:24 +00:00
uint a = 1 ;
2017-04-14 14:48:59 +00:00
}
}
) " ;
2017-08-29 15:58:38 +00:00
CHECK_WARNING ( text , " Unused local variable. " ) ;
2017-04-14 14:48:59 +00:00
}
2017-08-29 15:58:38 +00:00
BOOST_AUTO_TEST_CASE ( warn_unused_function_parameter )
2017-04-14 14:48:59 +00:00
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( uint a ) pure public {
2017-04-14 14:48:59 +00:00
}
}
) " ;
2017-08-29 15:58:38 +00:00
CHECK_WARNING ( text , " Unused function parameter. Remove or comment out the variable name to silence this warning. " ) ;
2017-04-14 14:48:59 +00:00
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( uint a ) pure public {
2017-04-14 14:48:59 +00:00
}
}
) " ;
2017-11-22 14:06:12 +00:00
CHECK_SUCCESS ( text ) ;
2017-04-14 14:48:59 +00:00
}
2017-08-29 15:58:38 +00:00
BOOST_AUTO_TEST_CASE ( warn_unused_return_parameter )
2017-04-14 14:48:59 +00:00
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint a ) {
2017-04-14 14:48:59 +00:00
}
}
) " ;
2017-08-29 15:58:38 +00:00
CHECK_WARNING ( text , " Unused function parameter. Remove or comment out the variable name to silence this warning. " ) ;
2017-05-02 15:14:42 +00:00
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint a ) {
2017-05-02 15:14:42 +00:00
return ;
}
}
) " ;
2017-08-29 15:58:38 +00:00
CHECK_WARNING ( text , " Unused function parameter. Remove or comment out the variable name to silence this warning. " ) ;
2017-04-14 14:48:59 +00:00
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint ) {
2017-04-14 14:48:59 +00:00
}
}
) " ;
2017-05-02 12:44:36 +00:00
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2017-04-28 20:28:03 +00:00
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint a ) {
2017-04-28 20:28:03 +00:00
a = 1 ;
}
}
) " ;
2017-05-02 12:44:36 +00:00
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2017-04-28 20:28:03 +00:00
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint a ) {
2017-04-28 20:28:03 +00:00
return 1 ;
}
}
) " ;
2017-05-02 12:44:36 +00:00
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2017-04-14 14:48:59 +00:00
}
2017-10-05 18:31:32 +00:00
BOOST_AUTO_TEST_CASE ( no_unused_warning_interface_arguments )
{
char const * text = R " (
interface I {
2018-01-31 16:42:46 +00:00
function f ( uint a ) pure external returns ( uint b ) ;
2017-10-05 18:31:32 +00:00
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( no_unused_warning_abstract_arguments )
{
char const * text = R " (
contract C {
function f ( uint a ) pure public returns ( uint b ) ;
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2017-04-14 14:48:59 +00:00
BOOST_AUTO_TEST_CASE ( no_unused_warnings )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( uint a ) pure public returns ( uint b ) {
2017-04-14 14:48:59 +00:00
uint c = 1 ;
b = a + c ;
}
}
) " ;
2017-05-02 12:44:36 +00:00
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2017-04-14 14:48:59 +00:00
}
BOOST_AUTO_TEST_CASE ( no_unused_dec_after_use )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-05-02 15:14:42 +00:00
a = 7 ;
uint a ;
2017-04-14 14:48:59 +00:00
}
}
) " ;
2017-05-02 12:44:36 +00:00
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2017-04-14 14:48:59 +00:00
}
2017-05-11 14:57:34 +00:00
BOOST_AUTO_TEST_CASE ( no_unused_inline_asm )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-05-11 14:57:34 +00:00
uint a ;
assembly {
a : = 1
}
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2017-04-14 14:48:59 +00:00
2017-02-02 11:39:12 +00:00
BOOST_AUTO_TEST_CASE ( shadowing_builtins_with_functions )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function keccak256 ( ) pure public { }
2017-02-02 11:39:12 +00:00
}
) " ;
CHECK_WARNING ( text , " shadows a builtin symbol " ) ;
}
BOOST_AUTO_TEST_CASE ( shadowing_builtins_with_variables )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-02-02 11:39:12 +00:00
uint msg ;
msg ;
}
}
) " ;
CHECK_WARNING ( text , " shadows a builtin symbol " ) ;
}
2017-08-04 17:05:38 +00:00
BOOST_AUTO_TEST_CASE ( shadowing_builtins_with_storage_variables )
{
char const * text = R " (
contract C {
uint msg ;
}
) " ;
CHECK_WARNING ( text , " shadows a builtin symbol " ) ;
}
BOOST_AUTO_TEST_CASE ( shadowing_builtin_at_global_scope )
{
char const * text = R " (
contract msg {
}
) " ;
CHECK_WARNING ( text , " shadows a builtin symbol " ) ;
}
2017-02-02 11:39:12 +00:00
BOOST_AUTO_TEST_CASE ( shadowing_builtins_with_parameters )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( uint require ) pure public {
2017-02-02 11:39:12 +00:00
require = 2 ;
}
}
) " ;
CHECK_WARNING ( text , " shadows a builtin symbol " ) ;
}
BOOST_AUTO_TEST_CASE ( shadowing_builtins_with_return_parameters )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public returns ( uint require ) {
2017-02-02 11:39:12 +00:00
require = 2 ;
}
}
) " ;
CHECK_WARNING ( text , " shadows a builtin symbol " ) ;
}
BOOST_AUTO_TEST_CASE ( shadowing_builtins_with_events )
{
char const * text = R " (
contract C {
event keccak256 ( ) ;
}
) " ;
CHECK_WARNING ( text , " shadows a builtin symbol " ) ;
}
BOOST_AUTO_TEST_CASE ( shadowing_builtins_ignores_struct )
{
char const * text = R " (
contract C {
struct a {
uint msg ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( shadowing_builtins_ignores_constructor )
{
char const * text = R " (
contract C {
2018-03-01 17:39:01 +00:00
constructor ( ) public { }
2017-02-02 11:39:12 +00:00
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2017-08-03 20:47:13 +00:00
BOOST_AUTO_TEST_CASE ( function_overload_is_not_shadowing )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public { }
function f ( uint ) pure public { }
2017-08-03 20:47:13 +00:00
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2017-08-04 17:05:38 +00:00
BOOST_AUTO_TEST_CASE ( function_override_is_not_shadowing )
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract D { function f ( ) pure public { } }
2017-08-04 17:05:38 +00:00
contract C is D {
2017-09-05 15:11:53 +00:00
function f ( uint ) pure public { }
2017-08-04 17:05:38 +00:00
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2017-10-04 15:09:52 +00:00
BOOST_AUTO_TEST_CASE ( event_parameter_cannot_shadow_state_variable )
{
char const * text = R " (
contract C {
address a ;
event E ( address a ) ;
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2017-06-13 14:42:58 +00:00
BOOST_AUTO_TEST_CASE ( callable_crash )
{
char const * text = R " (
contract C {
struct S { uint a ; bool x ; }
S public s ;
2017-09-05 15:11:53 +00:00
function C ( ) public {
2017-06-13 14:42:58 +00:00
3 ( { a : 1 , x : true } ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Type is not callable " ) ;
}
2017-07-09 01:42:42 +00:00
BOOST_AUTO_TEST_CASE ( error_transfer_non_payable_fallback )
{
2017-09-20 13:54:41 +00:00
// This used to be a test for a.transfer to generate a warning
// because A's fallback function is not payable.
2017-07-09 01:42:42 +00:00
char const * text = R " (
contract A {
2017-09-05 15:11:53 +00:00
function ( ) public { }
2017-07-09 01:42:42 +00:00
}
contract B {
A a ;
2017-09-05 15:11:53 +00:00
function ( ) public {
2017-07-09 01:42:42 +00:00
a . transfer ( 100 ) ;
}
}
) " ;
2017-09-20 13:54:41 +00:00
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : Warning , " Using contract member \" transfer \" inherited from the address type is deprecated " } ,
{ Error : : Type : : TypeError , " Value transfer to a contract without a payable fallback function " }
} ) ) ;
2017-07-09 01:42:42 +00:00
}
BOOST_AUTO_TEST_CASE ( error_transfer_no_fallback )
{
2017-09-20 13:54:41 +00:00
// This used to be a test for a.transfer to generate a warning
// because A does not have a payable fallback function.
std : : string text = R " (
2017-07-09 01:42:42 +00:00
contract A { }
contract B {
A a ;
2017-09-05 15:11:53 +00:00
function ( ) public {
2017-07-09 01:42:42 +00:00
a . transfer ( 100 ) ;
}
}
) " ;
2017-09-20 13:54:41 +00:00
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : Warning , " Using contract member \" transfer \" inherited from the address type is deprecated " } ,
{ Error : : Type : : TypeError , " Value transfer to a contract without a payable fallback function " }
} ) ) ;
2017-07-09 01:42:42 +00:00
}
BOOST_AUTO_TEST_CASE ( error_send_non_payable_fallback )
{
2017-09-20 13:54:41 +00:00
// This used to be a test for a.send to generate a warning
// because A does not have a payable fallback function.
std : : string text = R " (
2017-07-09 01:42:42 +00:00
contract A {
2017-09-05 15:11:53 +00:00
function ( ) public { }
2017-07-09 01:42:42 +00:00
}
contract B {
A a ;
2017-09-05 15:11:53 +00:00
function ( ) public {
2017-07-09 01:42:42 +00:00
require ( a . send ( 100 ) ) ;
}
}
) " ;
2017-09-20 13:54:41 +00:00
CHECK_ALLOW_MULTI ( text , ( std : : vector < std : : pair < Error : : Type , std : : string > > {
{ Error : : Type : : Warning , " Using contract member \" send \" inherited from the address type is deprecated " } ,
{ Error : : Type : : TypeError , " Value transfer to a contract without a payable fallback function " }
} ) ) ;
2017-07-09 01:42:42 +00:00
}
BOOST_AUTO_TEST_CASE ( does_not_error_transfer_payable_fallback )
{
2017-09-20 13:54:41 +00:00
// This used to be a test for a.transfer to generate a warning
// because A does not have a payable fallback function.
2017-07-09 01:42:42 +00:00
char const * text = R " (
contract A {
2017-09-05 15:11:53 +00:00
function ( ) payable public { }
2017-07-09 01:42:42 +00:00
}
contract B {
A a ;
2017-09-05 15:11:53 +00:00
function ( ) public {
2017-07-09 01:42:42 +00:00
a . transfer ( 100 ) ;
}
}
) " ;
2017-09-20 13:54:41 +00:00
CHECK_WARNING ( text , " Using contract member \" transfer \" inherited from the address type is deprecated. " ) ;
2017-07-09 01:42:42 +00:00
}
2017-07-13 13:10:34 +00:00
BOOST_AUTO_TEST_CASE ( does_not_error_transfer_regular_function )
{
char const * text = R " (
contract A {
2017-09-05 15:11:53 +00:00
function transfer ( ) pure public { }
2017-07-13 13:10:34 +00:00
}
contract B {
A a ;
2017-09-05 15:11:53 +00:00
function ( ) public {
2017-08-30 22:27:25 +00:00
a . transfer ( ) ;
2017-07-13 13:10:34 +00:00
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2018-01-04 16:08:47 +00:00
BOOST_AUTO_TEST_CASE ( returndatasize_as_variable )
2017-06-08 15:17:43 +00:00
{
char const * text = R " (
2017-09-05 15:11:53 +00:00
contract c { function f ( ) public { uint returndatasize ; assembly { returndatasize } } }
2017-06-08 15:17:43 +00:00
) " ;
2018-02-23 18:29:42 +00:00
vector < pair < Error : : Type , std : : string > > expectations ( vector < pair < Error : : Type , std : : string > > {
2018-02-09 22:54:05 +00:00
{ Error : : Type : : Warning , " Variable is shadowed in inline assembly by an instruction of the same name " } ,
2018-02-15 16:25:54 +00:00
{ Error : : Type : : Warning , " The use of non-functional instructions is deprecated. " } ,
2018-02-23 18:29:42 +00:00
{ Error : : Type : : DeclarationError , " Unbalanced stack " }
} ) ;
2018-02-26 18:53:38 +00:00
if ( ! dev : : test : : Options : : get ( ) . evmVersion ( ) . supportsReturndata ( ) )
2018-02-23 18:29:42 +00:00
expectations . emplace_back ( make_pair ( Error : : Type : : Warning , std : : string ( " \" returndatasize \" instruction is only available for Byzantium-compatible " ) ) ) ;
CHECK_ALLOW_MULTI ( text , expectations ) ;
2017-06-08 15:17:43 +00:00
}
2017-04-14 14:48:59 +00:00
2017-06-14 14:06:48 +00:00
BOOST_AUTO_TEST_CASE ( create2_as_variable )
{
char const * text = R " (
2018-02-09 22:54:05 +00:00
contract c { function f ( ) public { uint create2 ; assembly { create2 ( 0 , 0 , 0 , 0 ) } } }
2017-06-14 14:06:48 +00:00
) " ;
2018-02-09 22:54:05 +00:00
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 " } ,
2018-02-23 18:29:57 +00:00
{ Error : : Type : : Warning , " The \" create2 \" instruction is not supported by the VM version " } ,
2018-02-15 16:25:54 +00:00
{ Error : : Type : : DeclarationError , " Unbalanced stack " } ,
{ Error : : Type : : Warning , " not supposed to return values " }
2018-02-09 22:54:05 +00:00
} ) ) ;
2017-06-14 14:06:48 +00:00
}
2017-07-05 17:38:00 +00:00
BOOST_AUTO_TEST_CASE ( warn_unspecified_storage )
{
char const * text = R " (
contract C {
2017-07-10 16:30:41 +00:00
struct S { uint a ; string b ; }
2017-07-05 17:38:00 +00:00
S x ;
2017-09-05 15:11:53 +00:00
function f ( ) view public {
2017-07-05 17:38:00 +00:00
S storage y = x ;
y ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
text = R " (
contract C {
struct S { uint a ; }
S x ;
2017-09-05 15:11:53 +00:00
function f ( ) view public {
2017-07-05 17:38:00 +00:00
S y = x ;
y ;
}
}
) " ;
2017-10-03 14:28:29 +00:00
CHECK_WARNING ( text , " Variable is declared as a storage pointer. Use an explicit \" storage \" keyword to silence this warning " ) ;
text = R " (
pragma experimental " v0.5.0 " ;
contract C {
struct S { uint a ; }
S x ;
function f ( ) view public {
S y = x ;
y ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Storage location must be specified as either \" memory \" or \" storage \" . " ) ;
2017-07-05 17:38:00 +00:00
}
2018-01-04 14:45:44 +00:00
BOOST_AUTO_TEST_CASE ( storage_location_non_array_or_struct_disallowed )
{
char const * text = R " (
contract C {
function f ( uint storage a ) public { }
}
) " ;
CHECK_ERROR ( text , TypeError , " Storage location can only be given for array or struct types. " ) ;
}
BOOST_AUTO_TEST_CASE ( storage_location_non_array_or_struct_disallowed_is_not_fatal )
{
char const * text = R " (
contract C {
function f ( uint storage a ) public {
a = f ;
}
}
) " ;
2018-02-09 22:54:05 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , ( std : : vector < std : : string > { " Storage location can only be given for array or struct types. " } ) ) ;
2018-01-04 14:45:44 +00:00
}
2017-07-11 13:51:58 +00:00
BOOST_AUTO_TEST_CASE ( implicit_conversion_disallowed )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public returns ( bytes4 ) {
2017-07-11 13:51:58 +00:00
uint32 tmp = 1 ;
return tmp ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Return argument type uint32 is not implicitly convertible to expected type (type of first return variable) bytes4. " ) ;
}
2017-06-13 14:25:52 +00:00
2017-07-12 19:22:47 +00:00
BOOST_AUTO_TEST_CASE ( too_large_arrays_for_calldata )
{
char const * text = R " (
contract C {
2016-11-18 03:14:13 +00:00
function f ( uint [ 85678901234 ] a ) pure external {
2017-07-12 19:22:47 +00:00
}
}
) " ;
2017-09-05 21:38:45 +00:00
CHECK_ERROR ( text , TypeError , " Array is too large to be encoded. " ) ;
2017-07-12 19:22:47 +00:00
text = R " (
contract C {
2016-11-18 03:14:13 +00:00
function f ( uint [ 85678901234 ] a ) pure internal {
2017-07-12 19:22:47 +00:00
}
}
) " ;
2017-09-05 21:38:45 +00:00
CHECK_ERROR ( text , TypeError , " Array is too large to be encoded. " ) ;
2017-07-12 19:22:47 +00:00
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( uint [ 85678901234 ] a ) pure public {
2017-07-12 19:22:47 +00:00
}
}
) " ;
2017-09-05 21:38:45 +00:00
CHECK_ERROR ( text , TypeError , " Array is too large to be encoded. " ) ;
2017-07-12 19:22:47 +00:00
}
2017-07-12 19:45:41 +00:00
BOOST_AUTO_TEST_CASE ( explicit_literal_to_storage_string )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-07-12 19:45:41 +00:00
string memory x = " abc " ;
x ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-07-12 19:45:41 +00:00
string storage x = " abc " ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Type literal_string \" abc \" is not implicitly convertible to expected type string storage pointer. " ) ;
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-07-12 19:45:41 +00:00
string x = " abc " ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Type literal_string \" abc \" is not implicitly convertible to expected type string storage pointer. " ) ;
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-07-12 19:45:41 +00:00
string ( " abc " ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Explicit type conversion not allowed from \" literal_string \" abc \" \" to \" string storage pointer \" " ) ;
}
2017-07-18 21:58:48 +00:00
BOOST_AUTO_TEST_CASE ( modifiers_access_storage_pointer )
{
char const * text = R " (
contract C {
2018-03-27 13:38:28 +00:00
struct S { uint a ; }
2017-07-18 21:58:48 +00:00
modifier m ( S storage x ) {
x ;
_ ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2017-06-27 11:15:51 +00:00
BOOST_AUTO_TEST_CASE ( function_types_sig )
{
char const * text = R " (
contract C {
2017-09-13 17:48:21 +00:00
function f ( ) view returns ( bytes4 ) {
2017-06-28 17:15:41 +00:00
return f . selector ;
2017-06-27 11:15:51 +00:00
}
}
) " ;
2017-06-28 17:15:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" selector \" not found " ) ;
2017-06-27 11:15:51 +00:00
text = R " (
contract C {
2017-09-13 17:48:21 +00:00
function g ( ) pure internal {
2017-06-27 11:15:51 +00:00
}
2017-09-13 17:48:21 +00:00
function f ( ) view returns ( bytes4 ) {
2017-06-28 17:15:41 +00:00
return g . selector ;
2017-06-27 11:15:51 +00:00
}
}
) " ;
2017-06-28 17:15:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" selector \" not found " ) ;
2017-06-27 11:15:51 +00:00
text = R " (
contract C {
2017-09-13 17:48:21 +00:00
function f ( ) view returns ( bytes4 ) {
2017-06-27 11:15:51 +00:00
function ( ) g ;
2017-06-28 17:15:41 +00:00
return g . selector ;
2017-06-27 11:15:51 +00:00
}
}
) " ;
2017-06-28 17:15:41 +00:00
CHECK_ERROR ( text , TypeError , " Member \" selector \" not found " ) ;
2017-06-27 11:15:51 +00:00
text = R " (
contract C {
2018-02-13 08:49:50 +00:00
function f ( ) pure external returns ( bytes4 ) {
2017-06-28 17:15:41 +00:00
return this . f . selector ;
2017-06-27 11:15:51 +00:00
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
text = R " (
contract C {
2017-09-13 17:48:21 +00:00
function h ( ) pure external {
2017-06-27 11:15:51 +00:00
}
2017-09-13 17:48:21 +00:00
function f ( ) view external returns ( bytes4 ) {
2017-06-27 11:15:51 +00:00
var g = this . h ;
2017-06-28 17:15:41 +00:00
return g . selector ;
2017-06-27 11:15:51 +00:00
}
}
) " ;
2018-02-12 22:26:13 +00:00
CHECK_WARNING ( text , " Use of the \" var \" keyword is deprecated. " ) ;
2017-06-27 11:15:51 +00:00
text = R " (
contract C {
2017-09-13 17:48:21 +00:00
function h ( ) pure external {
2017-06-27 11:15:51 +00:00
}
2017-09-13 17:48:21 +00:00
function f ( ) view external returns ( bytes4 ) {
function ( ) pure external g = this . h ;
2017-06-28 17:15:41 +00:00
return g . selector ;
2017-06-27 11:15:51 +00:00
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
text = R " (
contract C {
2017-09-13 17:48:21 +00:00
function h ( ) pure external {
2017-06-27 11:15:51 +00:00
}
2017-09-13 17:48:21 +00:00
function f ( ) view external returns ( bytes4 ) {
function ( ) pure external g = this . h ;
2017-06-27 11:15:51 +00:00
var i = g ;
2017-06-28 17:15:41 +00:00
return i . selector ;
2017-06-27 11:15:51 +00:00
}
}
) " ;
2018-02-12 22:26:13 +00:00
CHECK_WARNING ( text , " Use of the \" var \" keyword is deprecated. " ) ;
2017-06-27 11:15:51 +00:00
}
2017-02-05 19:06:04 +00:00
BOOST_AUTO_TEST_CASE ( using_this_in_constructor )
{
char const * text = R " (
contract C {
2018-03-01 17:39:01 +00:00
constructor ( ) public {
2017-02-05 19:06:04 +00:00
this . f ( ) ;
}
2017-09-05 15:11:53 +00:00
function f ( ) pure public {
2017-02-05 19:06:04 +00:00
}
}
) " ;
CHECK_WARNING ( text , " \" this \" used in constructor " ) ;
}
2017-07-31 19:54:54 +00:00
BOOST_AUTO_TEST_CASE ( do_not_crash_on_not_lvalue )
2017-07-26 12:19:32 +00:00
{
// This checks for a bug that caused a crash because of continued analysis.
char const * text = R " (
contract C {
mapping ( uint = > uint ) m ;
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-26 12:19:32 +00:00
m ( 1 ) = 2 ;
}
}
) " ;
2018-02-09 22:54:05 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , ( std : : vector < std : : string > {
" is not callable " ,
" Expression has to be an lvalue " ,
" Type int_const 2 is not implicitly "
} ) ) ;
2017-07-26 12:19:32 +00:00
}
2017-07-31 19:54:54 +00:00
BOOST_AUTO_TEST_CASE ( builtin_reject_gas )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-31 19:54:54 +00:00
keccak256 . gas ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" gas \" not found or not visible after argument-dependent lookup " ) ;
2017-07-31 19:54:54 +00:00
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-31 19:54:54 +00:00
sha256 . gas ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" gas \" not found or not visible after argument-dependent lookup " ) ;
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-31 19:54:54 +00:00
ripemd160 . gas ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" gas \" not found or not visible after argument-dependent lookup " ) ;
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-31 19:54:54 +00:00
ecrecover . gas ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" gas \" not found or not visible after argument-dependent lookup " ) ;
2017-07-31 19:54:54 +00:00
}
2018-03-05 17:01:42 +00:00
BOOST_AUTO_TEST_CASE ( gasleft )
2018-03-02 16:58:27 +00:00
{
char const * text = R " (
contract C {
2018-03-05 17:01:42 +00:00
function f ( ) public view returns ( uint256 val ) { return msg . gas ; }
2018-03-02 16:58:27 +00:00
}
) " ;
2018-03-05 22:13:51 +00:00
CHECK_WARNING ( text , " \" msg.gas \" has been deprecated in favor of \" gasleft() \" " ) ;
2018-03-02 16:58:27 +00:00
text = R " (
contract C {
2018-03-05 17:01:42 +00:00
function f ( ) public view returns ( uint256 val ) { return gasleft ( ) ; }
2018-03-02 16:58:27 +00:00
}
) " ;
2018-03-05 17:01:42 +00:00
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2018-03-02 16:58:27 +00:00
text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function f ( ) public returns ( uint256 val ) { return msg . gas ; }
}
) " ;
2018-03-05 22:13:51 +00:00
CHECK_ERROR ( text , TypeError , " \" msg.gas \" has been deprecated in favor of \" gasleft() \" " ) ;
2018-03-02 16:58:27 +00:00
}
2018-03-05 17:01:42 +00:00
BOOST_AUTO_TEST_CASE ( gasleft_shadowing )
2018-03-05 12:28:57 +00:00
{
char const * text = R " (
contract C {
function gasleft ( ) public pure returns ( bytes32 val ) { return " abc " ; }
2018-03-05 17:01:42 +00:00
function f ( ) public pure returns ( bytes32 val ) { return gasleft ( ) ; }
2018-03-05 12:28:57 +00:00
}
) " ;
CHECK_WARNING ( text , " This declaration shadows a builtin symbol. " ) ;
text = R " (
contract C {
uint gasleft ;
function f ( ) public { gasleft = 42 ; }
}
) " ;
CHECK_WARNING ( text , " This declaration shadows a builtin symbol. " ) ;
}
2017-07-31 19:54:54 +00:00
BOOST_AUTO_TEST_CASE ( builtin_reject_value )
{
char const * text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-31 19:54:54 +00:00
keccak256 . value ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" value \" not found or not visible after argument-dependent lookup " ) ;
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-31 19:54:54 +00:00
sha256 . value ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" value \" not found or not visible after argument-dependent lookup " ) ;
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-31 19:54:54 +00:00
ripemd160 . value ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" value \" not found or not visible after argument-dependent lookup " ) ;
text = R " (
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-07-31 19:54:54 +00:00
ecrecover . value ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" value \" not found or not visible after argument-dependent lookup " ) ;
}
2017-08-04 19:38:45 +00:00
BOOST_AUTO_TEST_CASE ( constructor_without_implementation )
{
char const * text = R " (
contract C {
function C ( ) ;
}
) " ;
CHECK_ERROR ( text , TypeError , " Constructor must be implemented if declared. " ) ;
}
2017-08-07 13:44:35 +00:00
BOOST_AUTO_TEST_CASE ( large_storage_array_fine )
{
char const * text = R " (
contract C {
uint [ 2 * * 64 - 1 ] x ;
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( large_storage_array_simple )
{
char const * text = R " (
contract C {
uint [ 2 * * 64 ] x ;
}
) " ;
CHECK_WARNING ( text , " covers a large part of storage and thus makes collisions likely " ) ;
}
BOOST_AUTO_TEST_CASE ( large_storage_arrays_combined )
{
char const * text = R " (
contract C {
uint [ 200 ] [ 200 ] [ 2 * * 30 ] [ ] [ 2 * * 30 ] x ;
}
) " ;
CHECK_WARNING ( text , " covers a large part of storage and thus makes collisions likely " ) ;
}
BOOST_AUTO_TEST_CASE ( large_storage_arrays_struct )
{
char const * text = R " (
contract C {
struct S { uint [ 2 * * 30 ] x ; uint [ 2 * * 50 ] y ; }
S [ 2 * * 20 ] x ;
}
) " ;
CHECK_WARNING ( text , " covers a large part of storage and thus makes collisions likely " ) ;
}
BOOST_AUTO_TEST_CASE ( large_storage_array_mapping )
{
char const * text = R " (
contract C {
mapping ( uint = > uint [ 2 * * 100 ] ) x ;
}
) " ;
CHECK_WARNING ( text , " covers a large part of storage and thus makes collisions likely " ) ;
}
2017-08-08 10:59:55 +00:00
BOOST_AUTO_TEST_CASE ( library_function_without_implementation )
2017-08-04 12:35:06 +00:00
{
char const * text = R " (
2017-08-08 10:59:55 +00:00
library L {
2017-09-05 15:11:53 +00:00
function f ( ) public ;
2017-08-04 12:35:06 +00:00
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2017-08-08 10:59:55 +00:00
text = R " (
2017-08-04 12:35:06 +00:00
library L {
function f ( ) internal ;
}
2017-08-08 10:59:55 +00:00
) " ;
CHECK_ERROR ( text , TypeError , " Internal library function must be implemented if declared. " ) ;
text = R " (
library L {
function f ( ) private ;
2017-08-04 12:35:06 +00:00
}
) " ;
2017-08-08 10:59:55 +00:00
CHECK_ERROR ( text , TypeError , " Internal library function must be implemented if declared. " ) ;
2017-08-04 12:35:06 +00:00
}
2017-08-21 14:22:20 +00:00
BOOST_AUTO_TEST_CASE ( using_for_with_non_library )
{
// This tests a crash that was resolved by making the first error fatal.
char const * text = R " (
library L {
struct S { uint d ; }
using S for S ;
function f ( S _s ) internal {
_s . d = 1 ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Library name expected. " ) ;
}
2017-08-08 13:41:46 +00:00
BOOST_AUTO_TEST_CASE ( experimental_pragma )
{
char const * text = R " (
pragma experimental ;
) " ;
CHECK_ERROR ( text , SyntaxError , " Experimental feature name is missing. " ) ;
text = R " (
pragma experimental 123 ;
) " ;
CHECK_ERROR ( text , SyntaxError , " Unsupported experimental feature name. " ) ;
text = R " (
pragma experimental unsupportedName ;
) " ;
CHECK_ERROR ( text , SyntaxError , " Unsupported experimental feature name. " ) ;
text = R " (
pragma experimental " unsupportedName " ;
) " ;
CHECK_ERROR ( text , SyntaxError , " Unsupported experimental feature name. " ) ;
text = R " (
pragma experimental " " ;
) " ;
CHECK_ERROR ( text , SyntaxError , " Empty experimental feature name is invalid. " ) ;
text = R " (
pragma experimental unsupportedName unsupportedName ;
) " ;
CHECK_ERROR ( text , SyntaxError , " Stray arguments. " ) ;
2017-08-10 16:09:44 +00:00
text = R " (
pragma experimental __test ;
) " ;
CHECK_WARNING ( text , " Experimental features are turned on. Do not use experimental features on live deployments. " ) ;
2018-02-09 22:54:05 +00:00
text = R " (
pragma experimental __test ;
pragma experimental __test ;
) " ;
CHECK_ERROR_ALLOW_MULTI ( text , SyntaxError , ( std : : vector < std : : string > { " Duplicate experimental feature name. " } ) ) ;
2017-08-08 13:41:46 +00:00
}
2017-08-11 23:45:37 +00:00
BOOST_AUTO_TEST_CASE ( reject_interface_creation )
{
char const * text = R " (
interface I { }
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-08-11 23:45:37 +00:00
new I ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Cannot instantiate an interface. " ) ;
}
BOOST_AUTO_TEST_CASE ( accept_library_creation )
{
char const * text = R " (
library L { }
contract C {
2017-09-05 15:11:53 +00:00
function f ( ) public {
2017-08-11 23:45:37 +00:00
new L ( ) ;
}
}
) " ;
CHECK_SUCCESS ( text ) ;
}
2017-08-21 14:43:15 +00:00
BOOST_AUTO_TEST_CASE ( reject_interface_constructors )
{
char const * text = R " (
interface I { }
contract C is I ( 2 ) { }
) " ;
CHECK_ERROR ( text , TypeError , " Wrong argument count for constructor call: 1 arguments given but expected 0. " ) ;
}
2017-09-16 15:10:23 +00:00
BOOST_AUTO_TEST_CASE ( non_external_fallback )
{
char const * text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function ( ) external { }
}
) " ;
2018-02-26 18:22:59 +00:00
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2017-09-16 15:10:23 +00:00
text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function ( ) internal { }
}
) " ;
CHECK_ERROR ( text , TypeError , " Fallback function must be defined as \" external \" . " ) ;
text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function ( ) private { }
}
) " ;
CHECK_ERROR ( text , TypeError , " Fallback function must be defined as \" external \" . " ) ;
text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function ( ) public { }
}
) " ;
CHECK_ERROR ( text , TypeError , " Fallback function must be defined as \" external \" . " ) ;
}
2017-09-18 10:39:17 +00:00
BOOST_AUTO_TEST_CASE ( invalid_literal_in_tuple )
{
char const * text = R " (
contract C {
function f ( ) pure public {
uint x ;
( x , ) = ( 1E111 ) ;
}
}
) " ;
2017-10-17 17:14:49 +00:00
CHECK_ERROR ( text , TypeError , " is not implicitly convertible to expected type " ) ;
2017-09-18 10:39:17 +00:00
text = R " (
contract C {
function f ( ) pure public {
uint x ;
( x , ) = ( 1 , 1E111 ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Invalid rational number. " ) ;
text = R " (
contract C {
function f ( ) pure public {
uint x ;
( x , ) = ( 1E111 , 1 ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Invalid rational number. " ) ;
2017-10-17 17:14:49 +00:00
text = R " (
contract C {
function f ( ) pure public {
( 2 * * 270 , 1 ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Invalid rational number. " ) ;
text = R " (
contract C {
function f ( ) pure public {
( ( 2 * * 270 ) / 2 * * 100 , 1 ) ;
}
}
) " ;
CHECK_SUCCESS ( text ) ;
2017-09-18 10:39:17 +00:00
}
2017-07-31 19:31:12 +00:00
BOOST_AUTO_TEST_CASE ( warn_about_sha3 )
{
char const * text = R " (
contract test {
function f ( ) pure public {
2018-02-12 22:09:14 +00:00
bytes32 x = sha3 ( uint8 ( 1 ) ) ;
2017-07-31 19:31:12 +00:00
x ;
}
}
) " ;
CHECK_WARNING ( text , " \" sha3 \" has been deprecated in favour of \" keccak256 \" " ) ;
}
BOOST_AUTO_TEST_CASE ( warn_about_suicide )
{
char const * text = R " (
contract test {
function f ( ) public {
suicide ( 1 ) ;
}
}
) " ;
CHECK_WARNING ( text , " \" suicide \" has been deprecated in favour of \" selfdestruct \" " ) ;
}
2017-09-20 10:14:28 +00:00
BOOST_AUTO_TEST_CASE ( address_overload_resolution )
{
char const * text = R " (
contract C {
function balance ( ) returns ( uint ) {
this . balance ; // to avoid pureness warning
return 1 ;
}
function transfer ( uint amount ) {
address ( this ) . transfer ( amount ) ; // to avoid pureness warning
}
}
contract D {
function f ( ) {
var x = ( new C ( ) ) . balance ( ) ;
x ;
( new C ( ) ) . transfer ( 5 ) ;
}
}
) " ;
CHECK_SUCCESS ( text ) ;
}
2017-10-05 19:08:12 +00:00
BOOST_AUTO_TEST_CASE ( array_length_invalid_expression )
{
char const * text = R " (
contract C {
uint [ - true ] ids ;
}
) " ;
2017-11-22 12:41:33 +00:00
CHECK_ERROR ( text , TypeError , " Invalid array length, expected integer literal or constant expression. " ) ;
2017-10-05 19:08:12 +00:00
text = R " (
contract C {
uint [ true / 1 ] ids ;
}
) " ;
2017-11-22 12:41:33 +00:00
CHECK_ERROR ( text , TypeError , " Invalid array length, expected integer literal or constant expression. " ) ;
2017-10-05 19:08:12 +00:00
text = R " (
contract C {
uint [ 1 / true ] ids ;
}
) " ;
2017-11-22 12:41:33 +00:00
CHECK_ERROR ( text , TypeError , " Invalid array length, expected integer literal or constant expression. " ) ;
2017-10-05 19:08:12 +00:00
text = R " (
contract C {
uint [ 1.111111E1111111111111 ] ids ;
}
) " ;
2017-11-22 12:41:33 +00:00
CHECK_ERROR ( text , TypeError , " Invalid array length, expected integer literal or constant expression. " ) ;
2017-10-04 09:59:21 +00:00
text = R " (
contract C {
uint [ 3 / 0 ] ids ;
}
) " ;
CHECK_ERROR ( text , TypeError , " Operator / not compatible with types int_const 3 and int_const 0 " ) ;
2017-10-05 19:08:12 +00:00
}
2017-09-20 13:54:41 +00:00
BOOST_AUTO_TEST_CASE ( warn_about_address_members_on_contract )
{
std : : string text = R " (
contract C {
function f ( ) view public {
this . balance ;
}
}
) " ;
CHECK_WARNING ( text , " Using contract member \" balance \" inherited from the address type is deprecated. " ) ;
text = R " (
contract C {
function f ( ) view public {
this . transfer ;
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( vector < pair < Error : : Type , std : : string > > {
{ Error : : Type : : Warning , " Using contract member \" transfer \" inherited from the address type is deprecated " } ,
{ Error : : Type : : TypeError , " Value transfer to a contract without a payable fallback function " }
} ) ) ;
text = R " (
contract C {
function f ( ) view public {
this . send ;
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( vector < pair < Error : : Type , std : : string > > {
{ Error : : Type : : Warning , " Using contract member \" send \" inherited from the address type is deprecated " } ,
{ Error : : Type : : TypeError , " Value transfer to a contract without a payable fallback function " }
} ) ) ;
text = R " (
contract C {
function f ( ) view public {
this . call ;
}
}
) " ;
CHECK_WARNING ( text , " Using contract member \" call \" inherited from the address type is deprecated. " ) ;
text = R " (
contract C {
function f ( ) view public {
this . callcode ;
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( vector < pair < Error : : Type , std : : string > > {
{ Error : : Type : : Warning , " Using contract member \" callcode \" inherited from the address type is deprecated " } ,
{ Error : : Type : : Warning , " \" callcode \" has been deprecated in favour of \" delegatecall \" " }
} ) ) ;
text = R " (
contract C {
function f ( ) view public {
this . delegatecall ;
}
}
) " ;
CHECK_WARNING ( text , " Using contract member \" delegatecall \" inherited from the address type is deprecated. " ) ;
}
BOOST_AUTO_TEST_CASE ( warn_about_address_members_on_non_this_contract )
{
std : : string text = R " (
contract C {
function f ( ) view public {
C c ;
c . balance ;
}
}
) " ;
CHECK_WARNING ( text , " Using contract member \" balance \" inherited from the address type is deprecated " ) ;
text = R " (
contract C {
function f ( ) view public {
C c ;
c . transfer ;
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( vector < pair < Error : : Type , std : : string > > {
{ Error : : Type : : Warning , " Using contract member \" transfer \" inherited from the address type is deprecated " } ,
{ Error : : Type : : TypeError , " Value transfer to a contract without a payable fallback function " }
} ) ) ;
text = R " (
contract C {
function f ( ) view public {
C c ;
c . send ;
}
}
) " ;
CHECK_ALLOW_MULTI ( text , ( vector < pair < Error : : Type , std : : string > > {
{ Error : : Type : : Warning , " Using contract member \" send \" inherited from the address type is deprecated " } ,
{ Error : : Type : : TypeError , " Value transfer to a contract without a payable fallback function " }
} ) ) ;
text = R " (
contract C {
function f ( ) pure public {
C c ;
c . call ;
}
}
) " ;
CHECK_WARNING ( text , " Using contract member \" call \" inherited from the address type is deprecated " ) ;
text = R " (
contract C {
function f ( ) pure public {
C c ;
c . callcode ;
}
}
) " ;
CHECK_WARNING_ALLOW_MULTI ( text , ( std : : vector < std : : string > {
" Using contract member \" callcode \" inherited from the address type is deprecated " ,
" \" callcode \" has been deprecated in favour of \" delegatecall \" "
} ) ) ;
text = R " (
contract C {
function f ( ) pure public {
C c ;
c . delegatecall ;
}
}
) " ;
CHECK_WARNING ( text , " Using contract member \" delegatecall \" inherited from the address type is deprecated " ) ;
}
2017-09-27 13:11:44 +00:00
BOOST_AUTO_TEST_CASE ( no_address_members_on_contract )
{
char const * text = R " (
pragma experimental " v0.5.0 " ;
contract C {
2018-02-27 14:21:23 +00:00
function f ( ) public {
2017-09-27 13:11:44 +00:00
this . balance ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" balance \" not found or not visible after argument-dependent lookup in contract " ) ;
text = R " (
pragma experimental " v0.5.0 " ;
contract C {
2018-02-27 14:21:23 +00:00
function f ( ) public {
2017-09-27 13:11:44 +00:00
this . transfer ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" transfer \" not found or not visible after argument-dependent lookup in contract " ) ;
text = R " (
pragma experimental " v0.5.0 " ;
contract C {
2018-02-27 14:21:23 +00:00
function f ( ) public {
2017-09-27 13:11:44 +00:00
this . send ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" send \" not found or not visible after argument-dependent lookup in contract " ) ;
text = R " (
pragma experimental " v0.5.0 " ;
contract C {
2018-02-27 14:21:23 +00:00
function f ( ) public {
2017-09-27 13:11:44 +00:00
this . call ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" call \" not found or not visible after argument-dependent lookup in contract " ) ;
text = R " (
pragma experimental " v0.5.0 " ;
contract C {
2018-02-27 14:21:23 +00:00
function f ( ) public {
2017-09-27 13:11:44 +00:00
this . callcode ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" callcode \" not found or not visible after argument-dependent lookup in contract " ) ;
text = R " (
pragma experimental " v0.5.0 " ;
contract C {
2018-02-27 14:21:23 +00:00
function f ( ) public {
2017-09-27 13:11:44 +00:00
this . delegatecall ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" delegatecall \" not found or not visible after argument-dependent lookup in contract " ) ;
}
2017-09-20 13:54:41 +00:00
BOOST_AUTO_TEST_CASE ( no_warning_for_using_members_that_look_like_address_members )
{
char const * text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function transfer ( uint ) public ;
function f ( ) public {
this . transfer ( 10 ) ;
}
}
) " ;
2018-03-06 19:15:43 +00:00
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2017-09-20 13:54:41 +00:00
}
2018-02-16 15:55:21 +00:00
BOOST_AUTO_TEST_CASE ( emit_events )
{
char const * text = R " (
contract C {
event e ( ) ;
function f ( ) public {
emit e ( ) ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
text = R " (
contract C {
event e ( uint a , string b ) ;
function f ( ) public {
emit e ( 2 , " abc " ) ;
emit e ( { b : " abc " , a : 8 } ) ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
text = R " (
contract A { event e ( uint a , string b ) ; }
contract C is A {
function f ( ) public {
emit A . e ( 2 , " abc " ) ;
emit A . e ( { b : " abc " , a : 8 } ) ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2018-02-16 16:32:54 +00:00
BOOST_AUTO_TEST_CASE ( old_style_events_050 )
{
char const * text = R " (
contract C {
event e ( ) ;
function f ( ) public {
e ( ) ;
}
}
) " ;
CHECK_WARNING ( text , " without \" emit \" prefix " ) ;
text = R " (
pragma experimental " v0.5.0 " ;
contract C {
event e ( ) ;
function f ( ) public {
e ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " have to be prefixed " ) ;
}
2018-02-26 10:13:21 +00:00
BOOST_AUTO_TEST_CASE ( getter_is_memory_type )
{
char const * text = R " (
contract C {
struct S { string m ; }
string [ ] public x ;
S [ ] public y ;
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
// Check that the getters return a memory strings, not a storage strings.
ContractDefinition const & c = dynamic_cast < ContractDefinition const & > ( * m_compiler . ast ( " " ) . nodes ( ) . at ( 1 ) ) ;
BOOST_CHECK ( c . interfaceFunctions ( ) . size ( ) = = 2 ) ;
for ( auto const & f : c . interfaceFunctions ( ) )
{
auto const & retType = f . second - > returnParameterTypes ( ) . at ( 0 ) ;
BOOST_CHECK ( retType - > dataStoredIn ( DataLocation : : Memory ) ) ;
}
}
2018-02-27 14:21:23 +00:00
BOOST_AUTO_TEST_CASE ( require_visibility_specifiers )
{
char const * text = R " (
contract C {
function f ( ) pure { }
}
) " ;
CHECK_WARNING ( text , " No visibility specified. Defaulting to " ) ;
text = R " (
pragma experimental " v0.5.0 " ;
contract C {
function f ( ) pure { }
}
) " ;
CHECK_ERROR ( text , SyntaxError , " No visibility specified. " ) ;
}
2018-03-07 09:48:10 +00:00
BOOST_AUTO_TEST_CASE ( blockhash )
2018-03-05 18:24:33 +00:00
{
2018-03-07 09:48:10 +00:00
char const * code = R " (
contract C {
function f ( ) public view returns ( bytes32 ) {
return block . blockhash ( 3 ) ;
2018-03-05 18:24:33 +00:00
}
}
) " ;
2018-03-07 09:48:10 +00:00
CHECK_WARNING ( code , " \" block.blockhash() \" has been deprecated in favor of \" blockhash() \" " ) ;
code = R " (
contract C {
function f ( ) public view returns ( bytes32 ) { return blockhash ( 3 ) ; }
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( code ) ;
code = R " (
pragma experimental " v0.5.0 " ;
contract C {
function f ( ) public returns ( bytes32 ) { return block . blockhash ( 3 ) ; }
}
) " ;
CHECK_ERROR ( code , TypeError , " \" block.blockhash() \" has been deprecated in favor of \" blockhash() \" " ) ;
2018-03-05 18:24:33 +00:00
}
2014-10-13 13:07:21 +00:00
BOOST_AUTO_TEST_SUITE_END ( )
2014-10-16 12:08:54 +00:00
}
}
} // end namespaces