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-03-03 11:51:51 +00:00
# include <test/libsolidity/ErrorCheck.h>
# include <test/TestHelper.h>
2014-10-13 13:07:21 +00:00
2015-10-20 22:21:52 +00:00
# include <libsolidity/parsing/Scanner.h>
# include <libsolidity/parsing/Parser.h>
# include <libsolidity/analysis/NameAndTypeResolver.h>
2016-12-01 13:55:02 +00:00
# include <libsolidity/analysis/StaticAnalyzer.h>
2017-03-03 11:51:51 +00:00
# include <libsolidity/analysis/PostTypeChecker.h>
2016-01-14 01:58:09 +00:00
# include <libsolidity/analysis/SyntaxChecker.h>
2017-05-11 13:26:35 +00:00
# include <libsolidity/interface/ErrorReporter.h>
2015-10-20 22:21:52 +00:00
# include <libsolidity/analysis/GlobalContext.h>
# include <libsolidity/analysis/TypeChecker.h>
2017-03-03 11:51:51 +00:00
# include <libdevcore/SHA3.h>
# 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
2014-10-16 12:08:54 +00:00
namespace
{
2015-01-23 15:37:06 +00:00
2016-11-15 18:07:33 +00:00
pair < ASTPointer < SourceUnit > , std : : shared_ptr < Error const > >
2016-12-05 14:40:35 +00:00
parseAnalyseAndReturnError ( string const & _source , bool _reportWarnings = false , bool _insertVersionPragma = true , bool _allowMultipleErrors = false )
2014-10-16 12:08:54 +00:00
{
2016-08-19 17:57:21 +00:00
// Silence compiler version warning
2016-08-24 10:15:35 +00:00
string source = _insertVersionPragma ? " pragma solidity >=0.0; \n " + _source : _source ;
2015-10-14 18:37:41 +00:00
ErrorList errors ;
2017-05-11 13:26:35 +00:00
ErrorReporter errorReporter ( errors ) ;
Parser parser ( errorReporter ) ;
2015-09-16 14:56:30 +00:00
ASTPointer < SourceUnit > sourceUnit ;
// catch exceptions for a transition period
try
{
2016-08-19 17:57:21 +00:00
sourceUnit = parser . parse ( std : : make_shared < Scanner > ( CharStream ( source ) ) ) ;
2015-10-14 18:37:41 +00:00
if ( ! sourceUnit )
2016-11-09 09:48:45 +00:00
BOOST_FAIL ( " Parsing failed in type checker test. " ) ;
2015-10-14 18:37:41 +00:00
2017-05-11 13:26:35 +00:00
SyntaxChecker syntaxChecker ( errorReporter ) ;
2016-01-14 01:58:09 +00:00
if ( ! syntaxChecker . checkSyntax ( * sourceUnit ) )
2017-05-11 13:26:35 +00:00
return make_pair ( sourceUnit , errorReporter . errors ( ) . at ( 0 ) ) ;
2016-01-14 01:58:09 +00:00
2015-10-15 09:50:25 +00:00
std : : shared_ptr < GlobalContext > globalContext = make_shared < GlobalContext > ( ) ;
2017-01-31 21:59:56 +00:00
map < ASTNode const * , shared_ptr < DeclarationContainer > > scopes ;
2017-05-11 13:26:35 +00:00
NameAndTypeResolver resolver ( globalContext - > declarations ( ) , scopes , errorReporter ) ;
solAssert ( Error : : containsOnlyWarnings ( errorReporter . errors ( ) ) , " " ) ;
2015-10-14 18:37:41 +00:00
resolver . registerDeclarations ( * sourceUnit ) ;
2015-11-06 17:43:17 +00:00
bool success = true ;
2015-09-16 14:56:30 +00:00
for ( ASTPointer < ASTNode > const & node : sourceUnit - > nodes ( ) )
if ( ContractDefinition * contract = dynamic_cast < ContractDefinition * > ( node . get ( ) ) )
{
globalContext - > setCurrentContract ( * contract ) ;
resolver . updateDeclaration ( * globalContext - > currentThis ( ) ) ;
resolver . updateDeclaration ( * globalContext - > currentSuper ( ) ) ;
2015-11-06 19:56:14 +00:00
if ( ! resolver . resolveNamesAndTypes ( * contract ) )
2015-11-06 17:43:17 +00:00
success = false ;
2015-09-16 14:56:30 +00:00
}
2015-11-06 17:43:17 +00:00
if ( success )
for ( ASTPointer < ASTNode > const & node : sourceUnit - > nodes ( ) )
if ( ContractDefinition * contract = dynamic_cast < ContractDefinition * > ( node . get ( ) ) )
{
globalContext - > setCurrentContract ( * contract ) ;
resolver . updateDeclaration ( * globalContext - > currentThis ( ) ) ;
2015-10-14 18:37:41 +00:00
2017-05-11 13:26:35 +00:00
TypeChecker typeChecker ( errorReporter ) ;
2015-11-06 17:43:17 +00:00
bool success = typeChecker . checkTypeRequirements ( * contract ) ;
2017-05-11 13:26:35 +00:00
BOOST_CHECK ( success | | ! errorReporter . errors ( ) . empty ( ) ) ;
2015-09-16 14:56:30 +00:00
}
2016-12-01 13:55:02 +00:00
if ( success )
2017-05-11 13:26:35 +00:00
if ( ! PostTypeChecker ( errorReporter ) . check ( * sourceUnit ) )
2017-03-03 11:51:51 +00:00
success = false ;
if ( success )
2017-05-11 13:26:35 +00:00
if ( ! StaticAnalyzer ( errorReporter ) . analyze ( * sourceUnit ) )
2017-03-03 11:51:51 +00:00
success = false ;
2017-06-22 14:32:46 +00:00
std : : shared_ptr < Error const > error ;
2017-05-11 13:26:35 +00:00
for ( auto const & currentError : errorReporter . errors ( ) )
2015-11-06 17:43:17 +00:00
{
if (
( _reportWarnings & & currentError - > type ( ) = = Error : : Type : : Warning ) | |
( ! _reportWarnings & & currentError - > type ( ) ! = Error : : Type : : Warning )
)
2017-06-22 14:32:46 +00:00
{
if ( error & & ! _allowMultipleErrors )
2017-06-01 10:20:26 +00:00
{
string message ( " Multiple errors found: " ) ;
for ( auto const & e : errorReporter . errors ( ) )
if ( string const * description = boost : : get_error_info < errinfo_comment > ( * e ) )
message + = * description + " , " ;
BOOST_FAIL ( message ) ;
}
2017-06-22 14:32:46 +00:00
if ( ! error )
error = currentError ;
}
2015-11-06 17:43:17 +00:00
}
2017-06-22 14:32:46 +00:00
if ( error )
return make_pair ( sourceUnit , error ) ;
2015-09-16 14:56:30 +00:00
}
2016-05-10 08:46:25 +00:00
catch ( InternalCompilerError const & _e )
{
string message ( " Internal compiler error " ) ;
if ( string const * description = boost : : get_error_info < errinfo_comment > ( _e ) )
message + = " : " + * description ;
BOOST_FAIL ( message ) ;
}
2015-11-06 19:56:14 +00:00
catch ( Error const & _e )
2015-09-16 14:56:30 +00:00
{
2016-11-15 18:07:33 +00:00
return make_pair ( sourceUnit , std : : make_shared < Error const > ( _e ) ) ;
2015-09-16 14:56:30 +00:00
}
2016-05-10 08:46:25 +00:00
catch ( . . . )
2015-09-16 14:56:30 +00:00
{
2016-05-10 08:46:25 +00:00
BOOST_FAIL ( " Unexpected exception. " ) ;
2015-09-16 14:56:30 +00:00
}
2015-10-14 18:37:41 +00:00
return make_pair ( sourceUnit , nullptr ) ;
2015-09-16 14:56:30 +00:00
}
2015-01-07 01:07:34 +00:00
2015-10-15 14:46:02 +00:00
ASTPointer < SourceUnit > parseAndAnalyse ( string const & _source )
2015-09-16 14:56:30 +00:00
{
auto sourceAndError = parseAnalyseAndReturnError ( _source ) ;
2015-10-14 18:37:41 +00:00
BOOST_REQUIRE ( ! ! sourceAndError . first ) ;
2015-10-15 12:36:23 +00:00
BOOST_REQUIRE ( ! sourceAndError . second ) ;
2015-09-16 14:56:30 +00:00
return sourceAndError . first ;
2014-10-16 12:08:54 +00:00
}
2015-01-22 16:43:16 +00:00
2015-10-15 16:14:14 +00:00
bool success ( string const & _source )
2015-10-15 12:36:23 +00:00
{
2015-10-15 16:14:14 +00:00
return ! parseAnalyseAndReturnError ( _source ) . second ;
2015-10-15 12:36:23 +00:00
}
2016-12-05 14:40:35 +00:00
Error expectError ( std : : string const & _source , bool _warning = false , bool _allowMultiple = false )
2015-09-16 14:56:30 +00:00
{
2016-12-05 14:40:35 +00:00
auto sourceAndError = parseAnalyseAndReturnError ( _source , _warning , true , _allowMultiple ) ;
2015-09-16 14:56:30 +00:00
BOOST_REQUIRE ( ! ! sourceAndError . second ) ;
2015-10-14 18:37:41 +00:00
BOOST_REQUIRE ( ! ! sourceAndError . first ) ;
return * sourceAndError . second ;
2015-09-16 14:56:30 +00:00
}
2015-03-25 12:58:15 +00:00
2015-01-22 16:43:16 +00:00
static ContractDefinition const * retrieveContract ( ASTPointer < SourceUnit > _source , unsigned index )
{
ContractDefinition * contract ;
unsigned counter = 0 ;
2015-08-31 16:44:29 +00:00
for ( ASTPointer < ASTNode > const & node : _source - > nodes ( ) )
2015-01-22 16:43:16 +00:00
if ( ( contract = dynamic_cast < ContractDefinition * > ( node . get ( ) ) ) & & counter = = index )
return contract ;
2015-09-16 14:56:30 +00:00
return nullptr ;
2015-01-22 16:43:16 +00:00
}
2015-11-16 15:31:16 +00:00
static FunctionTypePointer retrieveFunctionBySignature (
2016-12-01 10:53:06 +00:00
ContractDefinition const & _contract ,
2015-09-29 16:22:02 +00:00
std : : string const & _signature
)
2015-01-22 16:43:16 +00:00
{
2016-10-05 10:30:28 +00:00
FixedHash < 4 > hash ( dev : : keccak256 ( _signature ) ) ;
2016-12-01 10:53:06 +00:00
return _contract . interfaceFunctions ( ) [ hash ] ;
2015-01-22 16:43:16 +00:00
}
2015-03-09 12:49:53 +00:00
2014-10-13 13:07:21 +00:00
}
2016-12-05 14:40:35 +00:00
# define CHECK_ERROR_OR_WARNING(text, typ, substring, warning, allowMulti) \
2016-11-21 18:31:31 +00:00
do \
{ \
2016-12-05 14:40:35 +00:00
Error err = expectError ( ( text ) , ( warning ) , ( allowMulti ) ) ; \
2016-11-21 18:31:31 +00:00
BOOST_CHECK ( err . type ( ) = = ( Error : : Type : : typ ) ) ; \
2016-12-06 09:35:56 +00:00
BOOST_CHECK ( searchErrorMessage ( err , ( substring ) ) ) ; \
2016-11-21 18:31:31 +00:00
} while ( 0 )
// [checkError(text, type, substring)] asserts that the compilation down to typechecking
// emits an error of type [type] and with a message containing [substring].
# define CHECK_ERROR(text, type, substring) \
2016-12-05 14:40:35 +00:00
CHECK_ERROR_OR_WARNING ( text , type , substring , false , false )
// [checkError(text, type, substring)] asserts that the compilation down to typechecking
// emits an error of type [type] and with a message containing [substring].
# define CHECK_ERROR_ALLOW_MULTI(text, type, substring) \
CHECK_ERROR_OR_WARNING ( text , type , substring , false , true )
2016-11-21 18:31:31 +00:00
2017-06-08 15:17:43 +00:00
// [checkWarning(text, substring)] asserts that the compilation down to typechecking
// emits a warning and with a message containing [substring].
2016-11-21 18:31:31 +00:00
# define CHECK_WARNING(text, substring) \
2016-12-05 14:40:35 +00:00
CHECK_ERROR_OR_WARNING ( text , Warning , substring , true , false )
2016-11-21 18:31:31 +00:00
2017-06-08 15:17:43 +00:00
// [checkWarningAllowMulti(text, substring)] aserts that the compilation down to typechecking
// emits a warning and with a message containing [substring].
# define CHECK_WARNING_ALLOW_MULTI(text, substring) \
CHECK_ERROR_OR_WARNING ( text , Warning , substring , true , true )
2016-11-21 18:31:31 +00:00
// [checkSuccess(text)] asserts that the compilation down to typechecking succeeds.
# define CHECK_SUCCESS(text) do { BOOST_CHECK(success((text))); } while(0)
2016-12-01 13:55:02 +00:00
# define CHECK_SUCCESS_NO_WARNINGS(text) \
do \
{ \
auto sourceAndError = parseAnalyseAndReturnError ( ( text ) , true ) ; \
BOOST_CHECK ( sourceAndError . second = = nullptr ) ; \
} \
while ( 0 )
2016-11-21 18:31:31 +00:00
2014-10-13 13:07:21 +00:00
BOOST_AUTO_TEST_SUITE ( SolidityNameAndTypeResolution )
BOOST_AUTO_TEST_CASE ( smoke_test )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
uint256 stateVariable1 ;
2017-04-14 14:48:59 +00:00
function fun ( uint256 arg1 ) { uint256 y ; y = arg1 ; }
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 ( double_stateVariable_declaration )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
uint256 variable ;
uint128 variable ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , DeclarationError , " Identifier already declared. " ) ;
2014-10-13 13:07:21 +00:00
}
BOOST_AUTO_TEST_CASE ( double_function_declaration )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
2017-04-14 14:48:59 +00:00
function fun ( ) { }
function fun ( ) { }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , DeclarationError , " Function with same name and arguments defined twice. " ) ;
2014-10-13 13:07:21 +00:00
}
BOOST_AUTO_TEST_CASE ( double_variable_declaration )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
function f ( ) {
uint256 x ;
if ( true ) { uint256 x ; }
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , DeclarationError , " Identifier already declared. " ) ;
2014-10-13 13:07:21 +00:00
}
BOOST_AUTO_TEST_CASE ( name_shadowing )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
uint256 variable ;
2017-05-02 12:44:36 +00:00
function f ( ) { uint32 variable ; variable = 2 ; }
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 ( name_references )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
uint256 variable ;
2017-04-14 14:48:59 +00:00
function f ( uint256 ) 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 ;
function f ( uint256 arg ) {
f ( notfound ) ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , DeclarationError , " Undeclared identifier. " ) ;
2014-10-13 13:07:21 +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 {
function g ( ) { f ( ) ; }
function f ( ) { }
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-10-15 13:54:41 +00:00
}
2014-11-13 00:12:57 +00:00
BOOST_AUTO_TEST_CASE ( struct_definition_directly_recursive )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
struct MyStructName {
address addr ;
MyStructName x ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Recursive struct definition. " ) ;
2014-11-13 00:12:57 +00:00
}
BOOST_AUTO_TEST_CASE ( struct_definition_indirectly_recursive )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
struct MyStructName1 {
address addr ;
uint256 count ;
MyStructName2 x ;
}
struct MyStructName2 {
MyStructName1 x ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Recursive struct definition. " ) ;
2014-11-13 00:12:57 +00:00
}
2015-06-18 14:35:25 +00:00
BOOST_AUTO_TEST_CASE ( struct_definition_not_really_recursive )
{
char const * text = R " (
contract test {
struct s1 { uint a ; }
struct s2 { s1 x ; s1 y ; }
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-06-18 14:35:25 +00:00
}
2014-11-13 00:12:57 +00:00
BOOST_AUTO_TEST_CASE ( struct_definition_recursion_via_mapping )
{
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
struct MyStructName1 {
address addr ;
uint256 count ;
mapping ( uint = > MyStructName1 ) x ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2014-11-13 00:12:57 +00:00
}
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 {
function f ( uint256 arg1 , uint32 arg2 ) returns ( bool ret ) {
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 {
function f ( ) returns ( bool r ) { return 1 > = 2 ; }
}
) " ;
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 {
function f ( ) returns ( bool r1 , bool r2 ) { return 1 > = 2 ; }
}
) " ;
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 {
function f ( ) returns ( uint256 r ) { return 1 > = 2 ; }
}
) " ;
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-04-14 14:48:59 +00:00
function f ( ) returns ( bool ) { return g ( 12 , true ) = = 3 ; }
function g ( uint256 , bool ) 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 {
function f ( ) { uint32 ( 2 ) = = int64 ( 2 ) ; }
}
) " ;
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 {
function f ( ) { int32 ( 2 ) = = uint64 ( 2 ) ; }
}
) " ;
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 {
function f ( ) returns ( int256 r ) { var x = int256 ( uint32 ( 2 ) ) ; return x ; }
}
) " ;
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 {
function f ( ) { var x = " 123456789012345678901234567890123 " ; }
}
) " ;
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 {
function fun ( ) {
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 {
function fun ( ) {
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 ;
function fun ( ) {
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 ;
function fun ( ) {
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 {
function test ( ) returns ( uint a ) { }
}
) " ;
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-04-14 14:48:59 +00:00
function fun ( ) returns ( bool ) {
2016-12-03 20:52:51 +00:00
return Second ( 1 ) . fun ( 1 , true , 3 ) > 0 ;
}
}
contract Second {
2017-04-14 14:48:59 +00:00
function fun ( uint , bool , uint ) 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 {
function fun ( ) returns ( bool ret ) {
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 {
function f ( ) returns ( bool ret ) {
return this . f < this . f ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Operator < not compatible " ) ;
text = R " (
contract C {
function f ( ) returns ( bool ret ) {
return f < f ;
}
}
) " ;
2017-06-26 21:01:35 +00:00
CHECK_ERROR ( text , TypeError , " Operator < not compatible " ) ;
text = R " (
contract C {
function f ( ) returns ( bool ret ) {
return f = = f ;
}
function g ( ) returns ( bool ret ) {
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 ;
function f ( ) returns ( bool ret ) {
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 )
{
ASTPointer < SourceUnit > sourceUnit ;
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract test {
function functionName ( bytes32 input ) returns ( bytes32 out ) ;
}
) " ;
2015-10-15 14:46:02 +00:00
ETH_TEST_REQUIRE_NO_THROW ( sourceUnit = parseAndAnalyse ( text ) , " Parsing and name Resolving failed " ) ;
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 )
{
ASTPointer < SourceUnit > sourceUnit ;
char const * text = R " (
contract base { function foo ( ) ; }
contract derived is base { function foo ( ) { } }
2016-12-03 20:52:51 +00:00
) " ;
2015-10-15 14:46:02 +00:00
ETH_TEST_REQUIRE_NO_THROW ( sourceUnit = parseAndAnalyse ( text ) , " Parsing and name Resolving failed " ) ;
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 )
{
ASTPointer < SourceUnit > sourceUnit ;
char const * text = R " (
contract base { function foo ( bool ) ; }
contract derived is base { function foo ( uint ) { } }
2016-12-03 20:52:51 +00:00
) " ;
2015-10-15 14:46:02 +00:00
ETH_TEST_REQUIRE_NO_THROW ( sourceUnit = parseAndAnalyse ( text ) , " Parsing and name Resolving failed " ) ;
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 )
{
ASTPointer < SourceUnit > sourceUnit ;
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 ;
2016-12-03 20:52:51 +00:00
function foo ( ) { b = new base ( ) ; }
}
) " ;
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 )
{
ASTPointer < SourceUnit > sourceUnit ;
char const * text = R " (
contract base { function foo ( ) ; }
contract derived is base { function foo ( ) { } }
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 )
{
ASTPointer < SourceUnit > sourceUnit ;
char const * text = R " (
contract base { function foo ( ) ; }
contract foo is base { function foo ( ) { } }
) " ;
ETH_TEST_REQUIRE_NO_THROW ( sourceUnit = parseAndAnalyse ( text ) , " Parsing and name resolving failed " ) ;
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 )
{
ASTPointer < SourceUnit > sourceUnit ;
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract Test {
function foo ( uint256 arg1 , uint64 arg2 , bool arg3 ) returns ( uint256 ret ) {
ret = arg1 + arg2 ;
}
}
) " ;
2015-10-15 14:46:02 +00:00
ETH_TEST_REQUIRE_NO_THROW ( sourceUnit = parseAndAnalyse ( text ) , " Parsing and name Resolving failed " ) ;
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 )
{
ASTPointer < SourceUnit > sourceUnit ;
2016-12-03 20:52:51 +00:00
char const * text = R " (
contract Test {
2017-04-14 14:48:59 +00:00
function boo ( uint , bytes32 , address ) returns ( uint ret ) {
2016-12-03 20:52:51 +00:00
ret = 5 ;
}
}
) " ;
2015-10-15 14:46:02 +00:00
ETH_TEST_REQUIRE_NO_THROW ( sourceUnit = parseAndAnalyse ( text ) , " Parsing and name Resolving failed " ) ;
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 )
{
ASTPointer < SourceUnit > sourceUnit ;
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
}
) " ;
2015-10-15 14:46:02 +00:00
ETH_TEST_REQUIRE_NO_THROW ( sourceUnit = parseAndAnalyse ( text ) , " Parsing and name Resolving failed " ) ;
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
ASTPointer < SourceUnit > sourceUnit ;
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
}
) " ;
2015-10-15 14:46:02 +00:00
ETH_TEST_REQUIRE_NO_THROW ( sourceUnit = parseAndAnalyse ( text ) , " Parsing and name Resolving failed " ) ;
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 ( ) ) ;
}
}
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 {
2016-12-03 20:52:51 +00:00
function externalCall ( ) {
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 {
2016-12-03 20:52:51 +00:00
function externalCall ( ) {
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 ;
function g ( C c ) { }
function internalCall ( ) {
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 ;
function g ( C c ) { }
function internalCall ( ) {
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 {
function gsf ( ) { }
function tgeo ( ) { }
}
) " ;
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 ;
function f ( ) { baseMember = 7 ; }
}
) " ;
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 " (
contract root { function rootFunction ( ) { } }
contract inter1 is root { function f ( ) { } }
contract inter2 is root { function f ( ) { } }
2015-01-26 09:20:46 +00:00
contract derived is root , inter2 , inter1 {
2015-01-15 19:04:06 +00:00
function g ( ) { f ( ) ; rootFunction ( ) ; }
}
) " ;
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 { }
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , " 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 " (
contract B { function f ( ) { } }
contract C is B { function f ( uint i ) { } }
) " ;
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 " (
contract A { function f ( uint a ) { } }
contract B { function f ( ) { } }
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 { } }
contract C is B { function f ( ) { } }
) " ;
2017-07-18 04:10:57 +00:00
CHECK_ERROR ( text , TypeError , " Overriding function should be declared constant. " ) ;
}
BOOST_AUTO_TEST_CASE ( illegal_override_add_constness )
{
char const * text = R " (
contract B { function f ( ) { } }
contract C is B { function f ( ) constant { } }
) " ;
CHECK_ERROR ( text , TypeError , " Overriding function should not be declared constant. " ) ;
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 " (
contract A { function f ( ) { uint8 x = C ( 0 ) . g ( ) ; } }
2017-04-14 14:48:59 +00:00
contract B { function f ( ) { } function g ( ) 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 " (
contract A { function A ( ) { } }
contract B is A { function f ( ) { A x = A ( 0 ) ; } }
) " ;
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 " (
contract A { function A ( ) { } }
contract B is A { function A ( ) returns ( uint8 r ) { } }
) " ;
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 " (
contract A { function A ( uint a ) { } }
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 " (
contract A { function A ( uint a ) { } }
contract B is A { }
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-19 22:08:48 +00:00
}
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 {
function f ( ) { A a = B ( 1 ) ; }
}
) " ;
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 {
function f ( ) { B b = A ( 1 ) ; }
}
) " ;
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 {
function b ( ) { }
}
contract B is A {
function f ( ) {
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 00:02:38 +00:00
BOOST_AUTO_TEST_CASE ( function_modifier_invocation )
{
char const * text = R " (
contract B {
function f ( ) mod1 ( 2 , true ) mod2 ( " 0123456 " ) { }
2016-09-05 12:54:50 +00:00
modifier mod1 ( uint a , bool b ) { if ( b ) _ ; }
modifier mod2 ( bytes7 a ) { while ( a = = " 1234567 " ) _ ; }
2015-01-22 00:02:38 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-22 00:02:38 +00:00
}
BOOST_AUTO_TEST_CASE ( invalid_function_modifier_type )
{
char const * text = R " (
contract B {
function f ( ) mod1 ( true ) { }
2016-09-05 12:54:50 +00:00
modifier mod1 ( uint a ) { if ( a > 0 ) _ ; }
2015-01-22 00:02:38 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Invalid type for argument in modifier invocation. Invalid implicit conversion from bool to uint256 requested. " ) ;
2015-01-22 00:02:38 +00:00
}
BOOST_AUTO_TEST_CASE ( function_modifier_invocation_parameters )
{
char const * text = R " (
contract B {
2015-03-09 12:49:53 +00:00
function f ( uint8 a ) mod1 ( a , true ) mod2 ( r ) returns ( bytes7 r ) { }
2016-09-05 12:54:50 +00:00
modifier mod1 ( uint a , bool b ) { if ( b ) _ ; }
modifier mod2 ( bytes7 a ) { while ( a = = " 1234567 " ) _ ; }
2015-01-22 00:02:38 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-22 00:02:38 +00:00
}
BOOST_AUTO_TEST_CASE ( function_modifier_invocation_local_variables )
{
char const * text = R " (
contract B {
function f ( ) mod ( x ) { uint x = 7 ; }
2016-09-05 12:54:50 +00:00
modifier mod ( uint a ) { if ( a > 0 ) _ ; }
2015-01-22 00:02:38 +00:00
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-22 00:02:38 +00:00
}
2017-06-23 16:55:47 +00:00
BOOST_AUTO_TEST_CASE ( function_modifier_double_invocation )
{
char const * text = R " (
contract B {
function f ( uint x ) mod ( x ) mod ( 2 ) { }
modifier mod ( uint a ) { if ( a > 0 ) _ ; }
}
) " ;
2017-07-27 09:52:42 +00:00
success ( text ) ;
2017-06-23 16:55:47 +00:00
}
BOOST_AUTO_TEST_CASE ( base_constructor_double_invocation )
{
char const * text = R " (
contract C { function C ( uint a ) { } }
contract B is C {
function B ( ) C ( 2 ) C ( 2 ) { }
}
) " ;
CHECK_ERROR ( text , DeclarationError , " Base constructor already provided " ) ;
}
2015-01-22 00:02:38 +00:00
BOOST_AUTO_TEST_CASE ( legal_modifier_override )
{
char const * text = R " (
2016-09-05 12:54:50 +00:00
contract A { modifier mod ( uint a ) { _ ; } }
contract B is A { modifier mod ( uint a ) { _ ; } }
2015-01-22 00:02:38 +00:00
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2015-01-22 00:02:38 +00:00
}
BOOST_AUTO_TEST_CASE ( illegal_modifier_override )
{
char const * text = R " (
2016-09-05 12:54:50 +00:00
contract A { modifier mod ( uint a ) { _ ; } }
contract B is A { modifier mod ( uint8 a ) { _ ; } }
2015-01-22 00:02:38 +00:00
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Override changes modifier signature. " ) ;
2015-01-22 00:02:38 +00:00
}
BOOST_AUTO_TEST_CASE ( modifier_overrides_function )
{
char const * text = R " (
2016-09-05 12:54:50 +00:00
contract A { modifier mod ( uint a ) { _ ; } }
2016-08-16 17:03:00 +00:00
contract B is A { function mod ( uint a ) { } }
2015-01-22 00:02:38 +00:00
) " ;
2016-12-14 13:18:11 +00:00
// Error: Identifier already declared.
// Error: Override changes modifier to function.
2017-07-30 01:19:41 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , DeclarationError , " Identifier already declared. " ) ;
2015-01-22 00:02:38 +00:00
}
BOOST_AUTO_TEST_CASE ( function_overrides_modifier )
{
char const * text = R " (
2016-08-16 17:03:00 +00:00
contract A { function mod ( uint a ) { } }
2016-09-05 12:54:50 +00:00
contract B is A { modifier mod ( uint a ) { _ ; } }
2015-01-22 00:02:38 +00:00
) " ;
2016-12-14 13:18:11 +00:00
// Error: Identifier already declared.
// Error: Override changes function to modifier.
2017-07-30 01:19:41 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , DeclarationError , " Identifier already declared. " ) ;
2015-01-22 00:02:38 +00:00
}
2015-01-23 01:35:27 +00:00
BOOST_AUTO_TEST_CASE ( modifier_returns_value )
{
char const * text = R " (
contract A {
2016-08-16 17:03:00 +00:00
function f ( uint a ) mod ( 2 ) returns ( uint r ) { }
2016-09-05 12:54:50 +00:00
modifier mod ( uint a ) { _ ; return 7 ; }
2015-01-23 01:35:27 +00:00
}
) " ;
2017-01-27 17:27:59 +00:00
CHECK_ERROR ( text , TypeError , " Return arguments not allowed. " ) ;
2015-01-23 01:35:27 +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 {
function fun ( ) {
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
2015-01-23 15:37:06 +00:00
ASTPointer < SourceUnit > source ;
ContractDefinition const * contract ;
2015-10-15 14:46:02 +00:00
ETH_TEST_CHECK_NO_THROW ( source = parseAndAnalyse ( text ) , " Parsing and Resolving names failed " ) ;
2015-01-28 17:06:45 +00:00
BOOST_REQUIRE ( ( contract = retrieveContract ( source , 0 ) ) ! = 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 ( ) ;
BOOST_CHECK_EQUAL ( returnParams . at ( 0 ) - > canonicalName ( false ) , " uint256 " ) ;
2015-01-29 15:39:30 +00:00
BOOST_CHECK ( function - > isConstant ( ) ) ;
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 ( ) ;
BOOST_CHECK_EQUAL ( params . at ( 0 ) - > canonicalName ( false ) , " uint256 " ) ;
returnParams = function - > returnParameterTypes ( ) ;
BOOST_CHECK_EQUAL ( returnParams . at ( 0 ) - > canonicalName ( false ) , " bytes4 " ) ;
2015-02-02 16:52:50 +00:00
BOOST_CHECK ( function - > isConstant ( ) ) ;
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 ( ) ;
BOOST_CHECK_EQUAL ( params . at ( 0 ) - > canonicalName ( false ) , " uint256 " ) ;
BOOST_CHECK_EQUAL ( params . at ( 1 ) - > canonicalName ( false ) , " uint256 " ) ;
returnParams = function - > returnParameterTypes ( ) ;
BOOST_CHECK_EQUAL ( returnParams . at ( 0 ) - > canonicalName ( false ) , " bytes4 " ) ;
2015-01-30 15:06:56 +00:00
BOOST_CHECK ( function - > isConstant ( ) ) ;
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 {
function fun ( ) {
uint64 ( 2 ) ;
}
uint256 foo ;
function foo ( ) { }
}
) " ;
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 {
function fun ( ) {
uint64 ( 2 ) ;
}
uint256 private foo ;
uint256 internal bar ;
}
) " ;
2015-01-22 16:43:16 +00:00
ASTPointer < SourceUnit > source ;
ContractDefinition const * contract ;
2015-10-15 14:46:02 +00:00
ETH_TEST_CHECK_NO_THROW ( source = parseAndAnalyse ( text ) , " Parsing and Resolving names failed " ) ;
2015-01-22 16:43:16 +00:00
BOOST_CHECK ( ( contract = retrieveContract ( source , 0 ) ) ! = 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 {
function getStateVar ( ) constant returns ( uint stateVar ) {
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 {
function foo ( ) returns ( uint256 ) { return Parent . m_aMember ; }
}
) " ;
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-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Internal 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 ;
}
contract Child is Parent {
function foo ( ) returns ( uint256 ) { return Parent . m_aMember ; }
}
) " ;
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 ;
}
contract Parent2 is Parent1 {
uint256 internal m_aMember2 ;
}
contract Child is Parent2 {
function foo ( ) returns ( uint256 ) { return Parent2 . m_aMember1 ; }
}
) " ;
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 {
function foo ( ) returns ( uint256 ) { return Child . m_aMember2 ; }
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 ;
function ( ) { x = 2 ; }
}
) " ;
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 ;
function ( uint a ) { x = 2 ; }
}
) " ;
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 {
function ( ) { }
}
) " ;
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 {
function ( ) returns ( uint ) { }
}
) " ;
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-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Fallback function cannot be declared constant. " ) ;
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 ;
function ( ) { x = 2 ; }
function ( ) { x = 3 ; }
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , DeclarationError , " Function with same name and arguments defined twice. " ) ;
2015-01-29 21:50:20 +00:00
}
BOOST_AUTO_TEST_CASE ( fallback_function_inheritance )
{
char const * text = R " (
contract A {
uint x ;
function ( ) { x = 1 ; }
}
contract C is A {
function ( ) { x = 2 ; }
}
) " ;
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 ) ;
2015-01-29 13:35:28 +00:00
function f ( ) { 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 ) ;
}
) " ;
BOOST_CHECK ( success ( text ) ) ;
}
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 ) ;
2015-01-29 13:35:28 +00:00
function f ( ) { 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 {
function dup ( ) returns ( uint ) {
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 {
function dup ( ) returns ( uint ) {
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 ( ) ;
function dup ( ) returns ( uint ) {
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 {
function f ( ) { 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 {
function f ( ) { }
}
contract d {
function g ( ) { 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 {
function g ( ) { 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 {
function g ( ) { 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 {
function g ( ) { 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 {
function a ( uint a , uint b ) returns ( uint r ) {
r = a + b ;
}
function b ( ) returns ( uint r ) {
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 {
function a ( uint a , uint b ) returns ( uint r ) {
r = a + b ;
}
function b ( ) returns ( uint r ) {
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 {
function a ( uint a , uint b ) returns ( uint r ) {
r = a + b ;
}
function b ( ) returns ( uint r ) {
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 {
function a ( uint a , uint b ) returns ( uint r ) {
r = a + b ;
}
function b ( ) returns ( uint r ) {
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 {
2016-12-03 20:52:51 +00:00
function f ( uint ) { }
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 {
function f ( uint [ ] constant a ) { }
}
) " ;
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , " Illegal use of \" constant \" specifier. " ) ;
}
2015-02-09 01:06:30 +00:00
BOOST_AUTO_TEST_CASE ( empty_name_return_parameter )
{
char const * text = R " (
contract test {
2016-12-03 20:52:51 +00:00
function f ( ) 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 {
2016-12-03 20:52:51 +00:00
function f ( uint , uint k ) 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 {
2016-12-03 20:52:51 +00:00
function f ( ) 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 {
function f ( ) { var ( x ) = f ( ) ; }
}
) " ;
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 {
2016-12-03 20:52:51 +00:00
function c ( ) {
a = 115792089237316195423570985008687907853269984665640564039458 ;
2015-02-06 12:38:10 +00:00
}
uint256 a ;
2016-12-03 20:52:51 +00:00
}
) " ;
2015-10-15 14:46:02 +00:00
ETH_TEST_CHECK_NO_THROW ( parseAndAnalyse ( sourceCodeFine ) ,
2015-03-06 11:50:31 +00:00
" Parsing and Resolving names failed " ) ;
2015-02-06 12:38:10 +00:00
char const * sourceCode = R " (
contract c {
2016-12-03 20:52:51 +00:00
function c ( ) {
2015-02-06 12:38:10 +00:00
a = 115792089237316195423570985008687907853269984665640564039458 ether ;
}
uint256 a ;
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Type int_const 115792089237316195423570985008687907853269984665640564039458000000000000000000 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 {
2015-02-10 14:43:13 +00:00
function f ( ) 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-04-14 14:48:59 +00:00
function f ( ) 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-04-14 14:48:59 +00:00
function f ( ) 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-04-14 14:48:59 +00:00
function f ( ) 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 {
function f ( ) returns ( uint ) {
uint8 x = 100 ;
return 10 < < x ;
}
}
) " ;
CHECK_WARNING ( sourceCode , " might overflow " ) ;
sourceCode = R " (
contract test {
function f ( ) returns ( uint ) {
uint8 x = 100 ;
return uint8 ( 10 ) < < x ;
}
}
) " ;
CHECK_SUCCESS ( sourceCode ) ;
sourceCode = R " (
contract test {
function f ( ) returns ( uint ) {
return 2 < < 80 ;
}
}
) " ;
CHECK_SUCCESS ( sourceCode ) ;
sourceCode = R " (
contract test {
function f ( ) returns ( uint ) {
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 {
function f ( ) returns ( uint ) {
var i = 1 ;
return i ;
}
}
) " ;
2017-06-26 07:49:45 +00:00
CHECK_WARNING ( sourceCode , " uint8, which can hold values between 0 and 255 " ) ;
sourceCode = R " (
contract test {
function f ( ) {
var i = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ;
i ;
}
}
) " ;
CHECK_WARNING ( sourceCode , " uint256, which can hold values between 0 and 115792089237316195423570985008687907853269984665640564039457584007913129639935 " ) ;
sourceCode = R " (
contract test {
function f ( ) {
var i = - 2 ;
i ;
}
}
) " ;
CHECK_WARNING ( sourceCode , " int8, which can hold values between -128 and 127 " ) ;
2017-06-22 13:22:49 +00:00
sourceCode = R " (
contract test {
function f ( ) {
for ( var i = 0 ; i < msg . data . length ; i + + ) { }
}
}
2017-06-26 07:49:45 +00:00
) " ;
2017-06-22 14:09:10 +00:00
CHECK_WARNING ( sourceCode , " uint8, which can hold " ) ;
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 {
function test ( ) returns ( Interface . MyEnum ) {
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 }
function test ( ) {
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 }
function test ( ) {
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 }
function test ( ) {
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 }
function test ( ) {
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 }
function test ( ) {
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 }
function test ( ) {
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 }
2016-12-03 20:52:51 +00:00
function test ( ) {
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
}
function a ( ) {
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 {
function g ( ) { f ( ) ; }
}
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 {
function g ( ) { base . f ( ) ; }
}
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 { }
function g ( ) { f ( ) ; }
}
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 ( external_base_visibility )
{
char const * sourceCode = R " (
contract base {
function f ( ) external { }
}
contract derived is base {
function g ( ) { base . f ( ) ; }
}
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
) " ;
2015-10-15 14:46:02 +00:00
ETH_TEST_CHECK_NO_THROW ( parseAndAnalyse ( sourceCode ) , " Parsing and Name Resolving failed " ) ;
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 {
function f ( uint a ) { uint8 [ a ] x ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Invalid array length, expected integer literal. " ) ;
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 {
function f ( uint a ) { uint8 [ - 1 ] x ; }
}
) " ;
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 ;
function f ( ) { 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 ;
function f ( ) { 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 ;
function f ( ) { 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 ;
function f ( ) { 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 ;
function f ( ) { 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
}
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
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : Fixed , 0 , 0 ) ) = = * make_shared < FixedPointType > ( 128 , 19 , FixedPointType : : Modifier : : Signed ) ) ;
BOOST_CHECK ( * Type : : fromElementaryTypeName ( ElementaryTypeNameToken ( Token : : UFixed , 0 , 0 ) ) = = * make_shared < FixedPointType > ( 128 , 19 , 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 ;
function f ( ) { byte a = arr [ 0 ] ; }
2016-12-03 20:52:51 +00:00
}
) " ;
2015-10-15 14:46:02 +00:00
ETH_TEST_REQUIRE_NO_THROW ( parseAndAnalyse ( text ) , " Type resolving failed " ) ;
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 ) ;
}
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 {
2015-03-12 13:15:04 +00:00
function changeIt ( ) { x = 9 ; }
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-03-01 15:34:29 +00:00
BOOST_AUTO_TEST_CASE ( assigning_state_to_const_variable )
{
char const * text = R " (
contract C {
address constant x = msg . sender ;
}
) " ;
2017-03-14 18:25:16 +00:00
// Change to TypeError for 0.5.0.
CHECK_WARNING ( text , " Initial value for constant variable has to be compile-time constant. " ) ;
2017-03-01 18:12:40 +00:00
}
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 " ;
function f ( ) {
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-03-01 18:12:40 +00:00
BOOST_AUTO_TEST_CASE ( assign_constant_function_value_to_constant )
{
char const * text = R " (
contract C {
function ( ) constant returns ( uint ) x ;
uint constant y = x ( ) ;
}
) " ;
2017-03-14 18:25:16 +00:00
// Change to TypeError for 0.5.0.
CHECK_WARNING ( text , " 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-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 {
function f ( ) returns ( uint ) { return 1 ; }
function f ( uint a ) returns ( uint ) { return a ; }
function g ( ) returns ( uint ) { return f ( 3 , 5 ) ; }
}
) " ;
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 {
function f ( uint8 a ) returns ( uint ) { return a ; }
function f ( uint a ) returns ( uint ) { return 2 * a ; }
function g ( ) returns ( uint ) { return f ( 1 ) ; }
}
) " ;
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 {
function f ( uint a ) returns ( uint ) { return 2 * a ; }
function g ( ) returns ( uint ) { var x = f ; return x ( 7 ) ; }
}
) " ;
2015-10-15 14:46:02 +00:00
ETH_TEST_REQUIRE_NO_THROW ( parseAndAnalyse ( sourceCode ) , " Type resolving failed " ) ;
2015-04-15 15:40:50 +00:00
}
BOOST_AUTO_TEST_CASE ( assignment_of_overloaded_function )
{
char const * sourceCode = R " (
contract test {
function f ( ) returns ( uint ) { return 1 ; }
function f ( uint a ) returns ( uint ) { return 2 * a ; }
function g ( ) returns ( uint ) { var x = f ; return x ( 7 ) ; }
}
) " ;
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 }
function f ( a ) { }
}
contract test is base {
function f ( uint8 a ) { }
}
) " ;
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 {
function f ( uint a ) returns ( uint ) { }
}
contract test is base {
function f ( uint a ) returns ( uint8 ) { }
}
) " ;
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 {
function test ( uint a ) { }
function test ( ) { }
}
) " ;
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 {
2015-04-15 15:40:50 +00:00
function test ( uint a ) returns ( uint b ) { }
function test ( uint a ) external { }
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR_ALLOW_MULTI ( sourceCode , DeclarationError , " Function with same name and arguments defined twice. " ) ;
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 {
function f ( ) returns ( uint ) { var x ; return 2 ; }
}
) " ;
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 ;
function f ( ) { var a = s [ 2 ] ; }
}
) " ;
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 ;
function f ( ) { var a = s . length ; }
}
) " ;
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 " (
contract test { function ( ) { uint x = 1 ; uint y = 2 ; x | | y ; } }
) " ;
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 " (
contract test { function ( ) { uint x = 1 ; uint y = 2 ; x & & y ; } }
) " ;
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 " (
contract test { function ( ) { uint x = 1 ; ! x ; } }
) " ;
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 " (
contract test { function ( ) { uint x = 3 ; int y = - 4 ; x * * y ; } }
) " ;
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 " (
contract test { function ( ) { uint x = 3 ; int y = - 4 ; y * * x ; } }
) " ;
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 " (
contract test { function ( ) { int x = - 3 ; int y = - 4 ; x * * y ; } }
) " ;
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 " (
contract test { bytes a ; bytes b ; function ( ) { a = = b ; } }
) " ;
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 " (
2015-08-10 21:49:46 +00:00
contract test { struct s { uint a ; } s x ; s y ; function ( ) { 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 {
function f ( ) {
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 {
function f ( ) {
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 ;
function f ( uint [ ] x ) {
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 ;
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 " ) ;
}
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 ;
function f ( ) {
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 ;
function f ( uint [ ] x ) {
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 {
}
function g ( uint [ ] x ) {
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 ) ;
}
function g ( uint [ ] 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 ( 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 {
function f ( uint ) returns ( string ) ;
function g ( ) {
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
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( sourceCode , TypeError , " Explicit type conversion not allowed from \" inaccessible dynamic type \" to \" bytes storage pointer \" . " ) ;
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 {
function f ( ) {
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 ; }
function f ( ) {
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 ; }
function f ( ) {
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 ; }
function f ( ) {
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 {
function f ( ) {
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 ;
function f ( ) {
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
}
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-04-14 14:48:59 +00:00
function min ( uint , uint ) returns ( uint ) ;
2015-09-10 17:40:07 +00:00
}
contract Test {
function f ( ) {
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 {
function f ( ) { 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 ;
function set5th ( ) returns ( bool ) {
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 {
function f ( ) { string x = " abc " ; }
}
) " ;
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
{
struct s {
uint a ;
}
function f ( )
{
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
}
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-05-11 12:43:29 +00:00
function f ( ) { 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 " (
contract A { function f ( ) { new B ( ) ; } }
contract B { function f ( ) { new C ( ) ; } }
contract C { function f ( ) { new A ( ) ; } }
) " ;
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 { }
contract B { function f ( ) { new C ( ) ; } }
contract C { function f ( ) { new A ( ) ; } }
) " ;
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-04-14 14:48:59 +00:00
contract C { function f ( ) { 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 {
function three ( ) returns ( uint , uint , uint ) ;
function two ( ) returns ( uint , uint ) ;
2015-10-13 10:22:57 +00:00
function none ( ) ;
2015-10-09 18:44:56 +00:00
function f ( ) {
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 {
function one ( ) returns ( uint ) ;
function f ( ) { var ( a , b , ) = one ( ) ; }
}
) " ;
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 {
function one ( ) returns ( uint ) ;
function f ( ) { var ( a , , ) = one ( ) ; }
}
) " ;
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 {
function one ( ) returns ( uint ) ;
function f ( ) { var ( , , a ) = one ( ) ; }
}
) " ;
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 {
function one ( ) returns ( uint ) ;
function f ( ) { var ( , a , b ) = one ( ) ; }
}
) " ;
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 {
function f ( ) {
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 {
function f ( ) {
( 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 {
function one ( ) returns ( uint ) ;
function f ( ) { var ( , ) = one ( ) ; }
}
) " ;
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 {
function two ( ) returns ( uint , uint ) ;
function f ( ) { var ( a , b , c ) = two ( ) ; }
}
) " ;
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 {
function f ( ) { }
function g ( ) {
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 {
function f ( ) returns ( uint a , uint b ) {
( 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 ;
function f ( ) {
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 " (
library D { function double ( uint self ) returns ( uint ) { return 2 * self ; } }
contract C {
using D for uint ;
function f ( uint a ) {
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 " (
library D { function double ( uint self ) returns ( uint ) { return 2 * self ; } }
contract C {
using D for uint ;
function f ( uint a ) returns ( uint ) {
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 " (
library D { struct s { uint a ; } function mul ( s storage self , uint x ) returns ( uint ) { return self . a * = x ; } }
contract C {
using D for D . s ;
D . s x ;
function f ( uint a ) returns ( uint ) {
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 ; }
function mul ( s storage self , uint x ) returns ( uint ) { return self . a * = x ; }
2017-04-14 14:48:59 +00:00
function mul ( s storage , bytes32 ) returns ( bytes32 ) { }
2015-11-25 13:23:35 +00:00
}
contract C {
using D for D . s ;
D . s x ;
function f ( uint a ) returns ( uint ) {
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 " (
library D { struct s { uint a ; } function mul ( s storage self , uint x ) returns ( uint ) { return self . a * = x ; } }
contract C {
using D for D . s ;
D . s x ;
function f ( uint a ) returns ( uint ) {
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 " (
library D { function double ( bytes32 self ) returns ( uint ) { return 2 ; } }
contract C {
using D for uint ;
function f ( uint a ) returns ( uint ) {
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 " (
library D { function double ( uint self ) returns ( uint ) { return 2 ; } }
contract C {
using D for uint ;
function f ( uint16 a ) returns ( uint ) {
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 " (
library c {
struct S { uint x ; }
function f ( ) returns ( S ) { }
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Internal type is not allowed for public or external functions. " ) ;
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 " (
library D { function double ( bytes32 self ) returns ( uint ) { return 2 ; } }
contract C {
using D for * ;
function f ( uint a ) returns ( uint ) {
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 " (
library D { struct s { uint a ; } function mul ( s storage self , uint x ) returns ( uint ) { return self . a * = x ; } }
contract C {
using D for D . s ;
D . s x ;
function f ( uint a ) returns ( uint ) {
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 {
function f ( uint size ) {
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 {
function f ( uint size ) {
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 {
function f ( uint size ) {
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 {
function f ( uint size ) {
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
}
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 {
function f ( ) returns ( uint ) {
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 {
2016-01-10 07:07:02 +00:00
function f ( ) returns ( string ) {
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 {
function f ( ) returns ( uint ) {
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 {
function f ( ) returns ( string ) {
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 {
function f ( ) returns ( uint ) {
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 {
function f ( ) returns ( string ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
[ 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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
2016-01-11 07:08:28 +00:00
uint x ;
uint y ;
( true ? x : y ) = 1 ;
2015-12-22 17:14:09 +00:00
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , " Conditional expression as left value is not supported yet. " ) ;
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 ;
}
function f ( ) {
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 {
function x ( bool ) { }
function y ( ) { }
function f ( ) {
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 }
function f ( ) {
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 ;
function f ( ) {
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 ;
function fun_x ( ) { }
function fun_y ( ) { }
enum small { A , B , C , D }
mapping ( uint8 = > uint8 ) table1 ;
mapping ( uint8 = > uint8 ) table2 ;
function f ( ) {
// 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
}
function f2 ( ) {
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
}
function f3 ( ) {
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-11 16:10:00 +00:00
BOOST_AUTO_TEST_CASE ( constructor_call_invalid_arg_count )
{
// This caused a segfault in an earlier version
char const * text = R " (
contract C {
function C ( ) { }
}
contract D is C {
function D ( ) C ( 5 ) { }
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Wrong argument count for modifier invocation: 1 arguments given but expected 0. " ) ;
2016-02-11 16:10:00 +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 ;
function f ( bytes16 b ) {
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 " ;
function f ( ) {
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 {
function f ( ) {
uintM something = 3 ;
intM should = 4 ;
bytesM fail = " now " ;
}
}
) " ;
BOOST_CHECK ( ! success ( text ) ) ;
}
2016-02-12 21:01:27 +00:00
BOOST_AUTO_TEST_CASE ( long_uint_variable_fails )
{
char const * text = R " (
contract test {
function f ( ) {
uint99999999999999999999999999 something = 3 ;
}
}
) " ;
BOOST_CHECK ( ! success ( text ) ) ;
}
2016-02-18 16:34:07 +00:00
BOOST_AUTO_TEST_CASE ( bytes10abc_is_identifier )
{
char const * text = R " (
contract test {
function f ( ) {
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 {
function f ( ) {
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 " (
2016-02-18 22:39:11 +00:00
library L { function l ( ) { } }
2016-03-10 19:25:14 +00:00
contract test {
function f ( ) {
2016-02-18 22:39:11 +00:00
L . l . value ;
2016-03-10 19:25:14 +00:00
}
}
) " ;
BOOST_CHECK ( ! success ( text ) ) ;
}
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 " (
library L { function l ( ) { } }
contract test {
function f ( ) {
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 {
function f ( ) {
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 {
2016-05-05 22:47:08 +00:00
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " Type fixed128x19 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 {
function f ( ) {
ufixed16x2 a = 3.25 ;
fixed16x2 b = - 3.25 ;
a ; b ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
text = R " (
2016-05-05 22:47:08 +00:00
contract test {
function f ( ) {
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 {
function f ( uint x ) {
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 " ) ;
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " Type ufixed128x19 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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
2017-07-12 13:44:27 +00:00
uint [ 3.5 ] a ; a ;
2016-02-18 22:39:11 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " Invalid array length, expected integer literal " ) ;
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 {
function f ( ) {
2017-07-12 13:44:27 +00:00
uint [ fixed ( 3.5 ) ] a ; a ;
2016-02-18 22:39:11 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " Invalid array length, expected integer literal " ) ;
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 {
function f ( ) {
2017-07-12 13:44:27 +00:00
uint [ ufixed ( 3.5 ) ] a ; a ;
2016-12-22 18:20:03 +00:00
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " Invalid array length, expected integer literal " ) ;
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 {
function f ( ) {
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 {
function f ( ) {
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
}
}
) " ;
2017-07-12 13:44:27 +00:00
CHECK_ERROR ( text , TypeError , " fixed128x19 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 ;
2016-02-18 22:39:11 +00:00
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
uint [ ] memory a ;
a [ .5 ] ;
}
}
) " ;
2017-07-12 13:44:27 +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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function b ( uint a ) {
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 {
function f ( ) {
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 ( signed_rational_modulus )
{
char const * text = R " (
contract test {
function f ( ) {
fixed a = 0.42578125 % - 0.4271087646484375 ;
fixed b = .5 % a ;
fixed c = a % b ;
}
}
) " ;
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 {
function f ( ) {
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 {
function g ( ) returns ( uint ) { }
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
address ( 0x12 ) . callcode ( " abc " ) ;
}
}
) " ;
2017-06-30 14:37:08 +00:00
CHECK_WARNING_ALLOW_MULTI ( text , " Return value of low-level calls not used " ) ;
2016-06-24 14:41:17 +00:00
}
BOOST_AUTO_TEST_CASE ( unused_return_value_delegatecall )
{
char const * text = R " (
contract test {
function f ( ) {
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 {
function f ( ) {
var x = address ( 0x12 ) . callcode ;
x ;
}
}
) " ;
CHECK_WARNING ( text , " \" callcode \" has been deprecated in favour " ) ;
}
BOOST_AUTO_TEST_CASE ( no_warn_about_callcode_as_local )
{
char const * text = R " (
contract test {
function callcode ( ) {
var x = this . callcode ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2016-08-06 13:08:06 +00:00
BOOST_AUTO_TEST_CASE ( modifier_without_underscore )
{
char const * text = R " (
contract test {
modifier m ( ) { }
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , SyntaxError , " Modifier body does not contain '_'. " ) ;
2016-08-26 18:37:10 +00:00
}
BOOST_AUTO_TEST_CASE ( payable_in_library )
{
char const * text = R " (
library test {
function f ( ) payable { }
}
) " ;
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 " (
contract B { function f ( ) payable { } }
contract C is B { function f ( ) { } }
) " ;
2017-07-18 04:10:57 +00:00
CHECK_ERROR ( text , TypeError , " Overriding function should be declared payable. " ) ;
2016-08-26 18:37:10 +00:00
}
BOOST_AUTO_TEST_CASE ( illegal_override_payable_nonpayable )
{
char const * text = R " (
contract B { function f ( ) { } }
contract C is B { function f ( ) payable { } }
) " ;
2017-07-18 04:10:57 +00:00
CHECK_ERROR ( text , TypeError , " Overriding function should not be declared 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 {
function ok ( ) returns ( bool ) { return true ; }
}
contract attr_func is attribute , func {
function checkOk ( ) returns ( bool ) { return ok ( ) ; }
}
) " ;
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 " (
contract receiver { function pay ( ) payable { } }
contract test {
2016-11-08 16:09:24 +00:00
function f ( ) { ( new receiver ( ) ) . pay . value ( 10 ) ( ) ; }
receiver r = new receiver ( ) ;
2016-08-26 18:37:10 +00:00
function g ( ) { r . pay . value ( 10 ) ( ) ; }
}
) " ;
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 " (
contract receiver { function nopay ( ) { } }
contract test {
2016-08-31 18:43:24 +00:00
function f ( ) { ( new receiver ( ) ) . nopay . value ( 10 ) ( ) ; }
}
) " ;
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 {
function f ( ) returns ( uint ) {
( 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 ) ;
BOOST_REQUIRE ( ! ! sourceAndError . second ) ;
BOOST_REQUIRE ( ! ! sourceAndError . first ) ;
2016-11-24 15:45:17 +00:00
BOOST_CHECK ( searchErrorMessage ( * sourceAndError . second , " 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 ;
) " ;
2016-11-15 18:07:33 +00:00
BOOST_CHECK ( expectError ( text , true ) . type ( ) = = Error : : Type : : SyntaxError ) ;
2016-08-19 17:57:21 +00:00
}
2016-09-06 01:51:01 +00:00
BOOST_AUTO_TEST_CASE ( constant_constructor )
{
char const * text = R " (
contract test {
function test ( ) constant { }
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Constructor cannot be defined as constant. " ) ;
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 ; }
2016-12-03 20:52:51 +00:00
function test ( uint k ) { 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 {
function b ( ) { }
}
contract A {
using B for bytes ;
function a ( ) {
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-27 19:37:32 +00:00
BOOST_AUTO_TEST_CASE ( function_type )
{
char const * text = R " (
contract C {
function f ( ) {
function ( uint ) returns ( uint ) x ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-09-27 19:37:32 +00:00
}
BOOST_AUTO_TEST_CASE ( function_type_parameter )
{
char const * text = R " (
contract C {
2016-10-13 15:51:46 +00:00
function f ( function ( uint ) external returns ( uint ) g ) returns ( function ( uint ) external returns ( uint ) ) {
return g ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-10-13 15:51:46 +00:00
}
BOOST_AUTO_TEST_CASE ( function_type_returned )
{
char const * text = R " (
contract C {
function f ( ) returns ( function ( uint ) external returns ( uint ) g ) {
2016-09-27 19:37:32 +00:00
return g ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-09-27 19:37:32 +00:00
}
BOOST_AUTO_TEST_CASE ( private_function_type )
{
char const * text = R " (
contract C {
function f ( ) {
function ( uint ) private returns ( uint ) x ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Invalid visibility, can only be \" external \" or \" internal \" . " ) ;
2016-09-27 19:37:32 +00:00
}
BOOST_AUTO_TEST_CASE ( public_function_type )
{
char const * text = R " (
contract C {
function f ( ) {
function ( uint ) public returns ( uint ) x ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Invalid visibility, can only be \" external \" or \" internal \" . " ) ;
2016-11-09 14:14:16 +00:00
}
BOOST_AUTO_TEST_CASE ( payable_internal_function_type )
{
char const * text = R " (
contract C {
function ( uint ) internal payable returns ( uint ) x ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Only external function types can be payable. " ) ;
2016-11-09 14:14:16 +00:00
}
BOOST_AUTO_TEST_CASE ( call_value_on_non_payable_function_type )
{
char const * text = R " (
contract C {
function ( uint ) external returns ( uint ) x ;
function f ( ) {
x . value ( 2 ) ( ) ;
}
}
) " ;
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 (uint256) external returns (uint256) - did you forget the \" payable \" modifier? " ) ;
2016-11-09 14:14:16 +00:00
}
2016-11-11 11:02:32 +00:00
BOOST_AUTO_TEST_CASE ( external_function_type_returning_internal )
{
char const * text = R " (
contract C {
function ( ) external returns ( function ( ) internal ) x ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Internal type cannot be used for external function type. " ) ;
2016-11-11 11:02:32 +00:00
}
BOOST_AUTO_TEST_CASE ( external_function_type_taking_internal )
{
char const * text = R " (
contract C {
function ( function ( ) internal ) external x ;
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Internal type cannot be used for external function type. " ) ;
2016-11-11 11:02:32 +00:00
}
2016-11-09 14:14:16 +00:00
BOOST_AUTO_TEST_CASE ( call_value_on_payable_function_type )
{
char const * text = R " (
contract C {
function ( uint ) external payable returns ( uint ) x ;
function f ( ) {
x . value ( 2 ) ( 1 ) ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-09-27 19:37:32 +00:00
}
2016-09-28 17:22:23 +00:00
BOOST_AUTO_TEST_CASE ( internal_function_as_external_parameter )
{
// It should not be possible to give internal functions
// as parameters to external functions.
char const * text = R " (
contract C {
2016-10-13 15:51:46 +00:00
function f ( function ( uint ) internal returns ( uint ) x ) {
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Internal type is not allowed for public or external functions. " ) ;
2016-10-13 15:51:46 +00:00
}
BOOST_AUTO_TEST_CASE ( internal_function_returned_from_public_function )
{
// It should not be possible to return internal functions from external functions.
char const * text = R " (
contract C {
function f ( ) returns ( function ( uint ) internal returns ( uint ) x ) {
2016-09-28 17:22:23 +00:00
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Internal type is not allowed for public or external functions. " ) ;
2016-09-28 17:22:23 +00:00
}
BOOST_AUTO_TEST_CASE ( internal_function_as_external_parameter_in_library_internal )
{
char const * text = R " (
library L {
2016-10-13 15:51:46 +00:00
function f ( function ( uint ) internal returns ( uint ) x ) internal {
2016-09-28 17:22:23 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-09-28 17:22:23 +00:00
}
2016-10-19 16:43:42 +00:00
2016-09-28 17:22:23 +00:00
BOOST_AUTO_TEST_CASE ( internal_function_as_external_parameter_in_library_external )
{
char const * text = R " (
library L {
2016-10-13 15:51:46 +00:00
function f ( function ( uint ) internal returns ( uint ) x ) {
2016-09-28 17:22:23 +00:00
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Internal type is not allowed for public or external functions. " ) ;
2016-09-28 17:22:23 +00:00
}
2016-09-27 19:37:32 +00:00
2016-10-19 16:43:42 +00:00
BOOST_AUTO_TEST_CASE ( function_type_arrays )
{
char const * text = R " (
contract C {
function ( uint ) external returns ( uint ) [ ] public x ;
function ( uint ) internal returns ( uint ) [ 10 ] y ;
function f ( ) {
function ( uint ) returns ( uint ) [ 10 ] memory a ;
function ( uint ) returns ( uint ) [ 10 ] storage b = y ;
function ( uint ) external returns ( uint ) [ ] memory c ;
c = new function ( uint ) external returns ( uint ) [ ] ( 200 ) ;
2017-04-14 14:48:59 +00:00
a ; b ;
2016-10-19 16:43:42 +00:00
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-10-19 16:43:42 +00:00
}
2016-11-09 08:36:38 +00:00
BOOST_AUTO_TEST_CASE ( delete_function_type )
{
char const * text = R " (
contract C {
function ( uint ) external returns ( uint ) x ;
function ( uint ) internal returns ( uint ) y ;
function f ( ) {
delete x ;
var a = y ;
delete a ;
delete y ;
var c = f ;
delete c ;
function ( uint ) internal returns ( uint ) g ;
delete g ;
}
}
) " ;
2016-11-21 18:31:31 +00:00
CHECK_SUCCESS ( text ) ;
2016-11-09 08:36:38 +00:00
}
BOOST_AUTO_TEST_CASE ( delete_function_type_invalid )
{
char const * text = R " (
contract C {
function f ( ) {
delete f ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Expression has to be an lvalue. " ) ;
2016-11-09 08:36:38 +00:00
}
BOOST_AUTO_TEST_CASE ( delete_external_function_type_invalid )
{
char const * text = R " (
contract C {
function f ( ) {
delete this . f ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Expression has to be an lvalue. " ) ;
2016-11-09 08:36:38 +00:00
}
2017-03-01 14:53:24 +00:00
BOOST_AUTO_TEST_CASE ( external_function_to_function_type_calldata_parameter )
{
// This is a test that checks that the type of the `bytes` parameter is
// correctly changed from its own type `bytes calldata` to `bytes memory`
// when converting to a function type.
char const * text = R " (
contract C {
2017-04-14 14:48:59 +00:00
function f ( function ( bytes memory ) external g ) { }
function callback ( bytes ) external { }
2017-03-01 14:53:24 +00:00
function g ( ) {
f ( this . callback ) ;
}
}
) " ;
CHECK_SUCCESS ( text ) ;
}
2016-12-02 21:53:36 +00:00
BOOST_AUTO_TEST_CASE ( external_function_type_to_address )
{
char const * text = R " (
contract C {
2017-01-27 11:46:36 +00:00
function f ( ) returns ( address ) {
2016-12-02 21:53:36 +00:00
return address ( this . f ) ;
}
}
) " ;
CHECK_SUCCESS ( text ) ;
}
2017-01-27 11:46:36 +00:00
BOOST_AUTO_TEST_CASE ( internal_function_type_to_address )
{
char const * text = R " (
contract C {
function f ( ) returns ( address ) {
return address ( f ) ;
}
}
) " ;
2017-02-01 20:47:56 +00:00
CHECK_ERROR ( text , TypeError , " Explicit type conversion not allowed " ) ;
}
BOOST_AUTO_TEST_CASE ( external_function_type_to_uint )
{
char const * text = R " (
contract C {
function f ( ) returns ( uint ) {
return uint ( this . f ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Explicit type conversion not allowed " ) ;
2017-01-27 11:46:36 +00:00
}
2017-06-24 17:09:19 +00:00
BOOST_AUTO_TEST_CASE ( warn_function_type_parameters_with_names )
{
char const * text = R " (
contract C {
function ( uint a ) f ;
}
) " ;
CHECK_WARNING ( text , " Naming function type parameters is deprecated. " ) ;
}
BOOST_AUTO_TEST_CASE ( warn_function_type_return_parameters_with_names )
{
char const * text = R " (
contract C {
function ( uint ) returns ( bool ret ) f ;
}
) " ;
CHECK_WARNING ( text , " Naming function type return parameters is deprecated. " ) ;
}
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
}
2016-10-20 00:15:39 +00:00
BOOST_AUTO_TEST_CASE ( inline_assembly_unbalanced_positive_stack )
{
char const * text = R " (
contract test {
function f ( ) {
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 {
function f ( ) {
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 " (
contract c {
uint8 x ;
function f ( ) {
assembly { x pop }
}
}
) " ;
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 " (
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
}
_ ;
}
function f ( ) m {
}
}
) " ;
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 " (
contract test {
uint x = 1 ;
function f ( ) {
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 " (
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
}
_ ;
}
function f ( ) m {
}
}
) " ;
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 " (
contract test {
uint constant x = 1 ;
function f ( ) {
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 " (
contract test {
uint constant x = 1 ;
function f ( ) {
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 " (
contract test {
function f ( ) {
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 " (
contract test {
uint [ ] r ;
function f ( ) {
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 " (
contract test {
uint a ;
function f ( ) {
assembly {
function g ( ) - > x { x : = a_slot }
}
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
2017-05-24 16:34:19 +00:00
}
2017-07-11 11:37:34 +00:00
BOOST_AUTO_TEST_CASE ( inline_assembly_calldata_variables )
{
char const * text = R " (
contract C {
function f ( bytes bytesAsCalldata ) external {
assembly {
let x : = bytesAsCalldata
}
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Call data elements cannot be accessed directly. " ) ;
}
2016-10-21 10:30:48 +00:00
BOOST_AUTO_TEST_CASE ( invalid_mobile_type )
{
char const * text = R " (
contract C {
function f ( ) {
// Invalid number
[ 1 , 78901234567890123456789012345678901234567890123456789345678901234567890012345678012345678901234567 ] ;
}
}
) " ;
2017-07-30 01:19:41 +00:00
CHECK_ERROR ( text , TypeError , " Invalid mobile type. " ) ;
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 {
function f ( ) {
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 {
function f ( ) payable {
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 {
function f ( ) internal {
msg . value ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
BOOST_AUTO_TEST_CASE ( does_not_warn_msg_value_in_library )
{
char const * text = R " (
library C {
function f ( ) {
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 {
function f ( ) { }
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 ;
function f ( ) { a = 2 ; }
}
) " ;
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 {
function f ( ) { var x = new C ( ) ; }
}
) " ;
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 ;
function B ( ) {
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 {
function D ( ) { }
}
) " ;
success ( text ) ;
}
2017-01-24 16:38:06 +00:00
BOOST_AUTO_TEST_CASE ( address_checksum_type_deduction )
{
char const * text = R " (
contract C {
function f ( ) {
var x = 0xfA0bFc97E48458494Ccd857e1A85DC91F7F0046E ;
x . send ( 2 ) ;
}
}
) " ;
success ( text ) ;
}
BOOST_AUTO_TEST_CASE ( invalid_address_checksum )
{
char const * text = R " (
contract C {
function f ( ) {
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
}
}
) " ;
CHECK_WARNING ( text , " checksum " ) ;
}
BOOST_AUTO_TEST_CASE ( invalid_address_no_checksum )
{
char const * text = R " (
contract C {
function f ( ) {
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
}
}
) " ;
CHECK_WARNING ( text , " checksum " ) ;
}
BOOST_AUTO_TEST_CASE ( invalid_address_length )
{
char const * text = R " (
contract C {
function f ( ) {
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
}
}
) " ;
CHECK_WARNING ( text , " checksum " ) ;
}
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 {
function f ( ) returns ( address ) {
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 {
function f ( ) {
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-03-03 13:33:54 +00:00
BOOST_AUTO_TEST_CASE ( cyclic_dependency_for_constants )
{
char const * text = R " (
contract C {
uint constant a = a ;
}
) " ;
CHECK_ERROR ( text , TypeError , " cyclic dependency via a " ) ;
text = R " (
contract C {
uint constant a = b * c ;
uint constant b = 7 ;
2017-05-11 12:43:29 +00:00
uint constant c = b + uint ( keccak256 ( d ) ) ;
2017-03-03 13:33:54 +00:00
uint constant d = 2 + a ;
}
) " ;
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , " a has a cyclic dependency via c " ) ;
text = R " (
contract C {
uint constant a = b * c ;
uint constant b = 7 ;
2017-05-11 12:43:29 +00:00
uint constant c = 4 + uint ( keccak256 ( d ) ) ;
2017-03-03 13:33:54 +00:00
uint constant d = 2 + b ;
}
) " ;
CHECK_SUCCESS ( text ) ;
}
2017-02-11 21:17:24 +00:00
BOOST_AUTO_TEST_CASE ( interface )
{
char const * text = R " (
interface I {
}
) " ;
success ( text ) ;
}
BOOST_AUTO_TEST_CASE ( interface_constructor )
{
char const * text = R " (
interface I {
function I ( ) ;
}
) " ;
2017-08-04 19:38:45 +00:00
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , " Constructor cannot be defined in interfaces " ) ;
2017-02-11 21:17:24 +00:00
}
BOOST_AUTO_TEST_CASE ( interface_functions )
{
char const * text = R " (
interface I {
function ( ) ;
function f ( ) ;
}
) " ;
success ( text ) ;
}
BOOST_AUTO_TEST_CASE ( interface_function_bodies )
{
char const * text = R " (
interface I {
function f ( ) {
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Functions in interfaces cannot have an implementation " ) ;
}
2017-03-17 16:59:36 +00:00
BOOST_AUTO_TEST_CASE ( interface_function_internal )
{
char const * text = R " (
interface I {
function f ( ) internal ;
}
) " ;
CHECK_ERROR ( text , TypeError , " Functions in interfaces cannot be internal or private. " ) ;
}
BOOST_AUTO_TEST_CASE ( interface_function_private )
{
char const * text = R " (
interface I {
function f ( ) private ;
}
) " ;
CHECK_ERROR ( text , TypeError , " Functions in interfaces cannot be internal or private. " ) ;
}
2017-02-11 21:17:24 +00:00
BOOST_AUTO_TEST_CASE ( interface_events )
{
char const * text = R " (
interface I {
event E ( ) ;
}
) " ;
success ( text ) ;
}
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 {
function f ( uint a ) returns ( bool ) ;
}
) " ;
success ( text ) ;
}
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 {
function f ( ) {
}
}
) " ;
success ( text ) ;
}
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 {
function f ( ) {
}
}
) " ;
success ( text ) ;
}
2017-07-05 17:45:12 +00:00
BOOST_AUTO_TEST_CASE ( warn_about_throw )
{
char const * text = R " (
contract C {
function f ( ) {
throw ;
}
}
) " ;
CHECK_WARNING ( text , " \" throw \" is deprecated " ) ;
}
2017-04-21 09:13:10 +00:00
BOOST_AUTO_TEST_CASE ( bare_revert )
{
char const * text = R " (
contract C {
function f ( uint x ) {
if ( x > 7 )
revert ;
}
}
) " ;
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-24 16:08:21 +00:00
BOOST_AUTO_TEST_CASE ( bare_others )
{
CHECK_WARNING ( " contract C { function f() { selfdestruct; } } " , " Statement has no effect. " ) ;
CHECK_WARNING ( " contract C { function f() { assert; } } " , " Statement has no effect. " ) ;
CHECK_WARNING ( " contract C { function f() { require; } } " , " Statement has no effect. " ) ;
CHECK_WARNING ( " contract C { function f() { suicide; } } " , " Statement has no effect. " ) ;
}
2017-04-21 09:13:10 +00:00
BOOST_AUTO_TEST_CASE ( pure_statement_in_for_loop )
{
char const * text = R " (
contract C {
function f ( ) {
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 {
function f ( ) {
for ( uint x = 0 ; true ; x + + )
{ }
}
}
) " ;
success ( text ) ;
}
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 ;
function f ( ) {
( 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 ;
function f ( ) {
( 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 ;
function f ( ) {
( , 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 ; }
function f ( ) {
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 ;
function f ( ) {
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 {
function f ( ) {
uint a ;
}
}
) " ;
CHECK_WARNING ( text , " Unused " ) ;
}
BOOST_AUTO_TEST_CASE ( warn_unused_local_assigned )
{
char const * text = R " (
contract C {
function f ( ) {
2017-06-22 14:54:24 +00:00
uint a = 1 ;
2017-04-14 14:48:59 +00:00
}
}
) " ;
CHECK_WARNING ( text , " Unused " ) ;
}
BOOST_AUTO_TEST_CASE ( warn_unused_param )
{
char const * text = R " (
contract C {
function f ( uint a ) {
}
}
) " ;
CHECK_WARNING ( text , " Unused " ) ;
text = R " (
contract C {
2017-05-02 12:44:36 +00:00
function f ( uint a ) {
2017-04-14 14:48:59 +00:00
}
}
) " ;
success ( text ) ;
}
BOOST_AUTO_TEST_CASE ( warn_unused_return_param )
{
char const * text = R " (
contract C {
function f ( ) returns ( uint a ) {
}
}
) " ;
CHECK_WARNING ( text , " Unused " ) ;
2017-05-02 15:14:42 +00:00
text = R " (
contract C {
function f ( ) returns ( uint a ) {
return ;
}
}
) " ;
CHECK_WARNING ( text , " Unused " ) ;
2017-04-14 14:48:59 +00:00
text = R " (
contract C {
function f ( ) returns ( uint ) {
}
}
) " ;
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 {
function f ( ) returns ( uint a ) {
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 {
function f ( ) returns ( uint a ) {
return 1 ;
}
}
) " ;
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_warnings )
{
char const * text = R " (
contract C {
function f ( uint a ) returns ( uint b ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
function keccak256 ( ) { }
}
) " ;
CHECK_WARNING ( text , " shadows a builtin symbol " ) ;
}
BOOST_AUTO_TEST_CASE ( shadowing_builtins_with_variables )
{
char const * text = R " (
contract C {
function f ( ) {
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 {
function f ( uint require ) {
require = 2 ;
}
}
) " ;
CHECK_WARNING ( text , " shadows a builtin symbol " ) ;
}
BOOST_AUTO_TEST_CASE ( shadowing_builtins_with_return_parameters )
{
char const * text = R " (
contract C {
function f ( ) returns ( uint require ) {
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 {
function C ( ) { }
}
) " ;
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 {
function f ( ) { }
function f ( uint ) { }
}
) " ;
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 " (
contract D { function f ( ) { } }
contract C is D {
function f ( uint ) { }
}
) " ;
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 ;
function C ( ) {
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 )
{
char const * text = R " (
contract A {
function ( ) { }
}
contract B {
A a ;
function ( ) {
a . transfer ( 100 ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Value transfer to a contract without a payable fallback function. " ) ;
}
BOOST_AUTO_TEST_CASE ( error_transfer_no_fallback )
{
char const * text = R " (
contract A { }
contract B {
A a ;
function ( ) {
a . transfer ( 100 ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Value transfer to a contract without a payable fallback function. " ) ;
}
BOOST_AUTO_TEST_CASE ( error_send_non_payable_fallback )
{
char const * text = R " (
contract A {
function ( ) { }
}
contract B {
A a ;
function ( ) {
require ( a . send ( 100 ) ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Value transfer to a contract without a payable fallback function. " ) ;
}
BOOST_AUTO_TEST_CASE ( does_not_error_transfer_payable_fallback )
{
char const * text = R " (
contract A {
function ( ) payable { }
}
contract B {
A a ;
function ( ) {
a . transfer ( 100 ) ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2017-07-13 13:10:34 +00:00
BOOST_AUTO_TEST_CASE ( does_not_error_transfer_regular_function )
{
char const * text = R " (
contract A {
function transfer ( uint ) { }
}
contract B {
A a ;
function ( ) {
a . transfer ( 100 ) ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2017-06-08 15:17:43 +00:00
BOOST_AUTO_TEST_CASE ( returndatacopy_as_variable )
{
char const * text = R " (
contract c { function f ( ) { uint returndatasize ; assembly { returndatasize } } }
) " ;
2017-06-09 13:35:27 +00:00
CHECK_WARNING_ALLOW_MULTI ( text , " Variable is shadowed in inline assembly by an instruction of the same name " ) ;
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 " (
contract c { function f ( ) { uint create2 ; assembly { create2 ( 0 , 0 , 0 , 0 ) } } }
) " ;
CHECK_WARNING_ALLOW_MULTI ( text , " Variable is shadowed in inline assembly by an instruction of the same name " ) ;
}
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 ;
function f ( ) {
S storage y = x ;
y ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
text = R " (
contract C {
struct S { uint a ; }
S x ;
function f ( ) {
S y = x ;
y ;
}
}
) " ;
CHECK_WARNING ( text , " is declared as a storage pointer. Use an explicit \" storage \" keyword to silence this warning " ) ;
}
2017-07-11 13:51:58 +00:00
BOOST_AUTO_TEST_CASE ( implicit_conversion_disallowed )
{
char const * text = R " (
contract C {
function f ( ) returns ( bytes4 ) {
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 {
function f ( uint [ 85678901234 ] a ) external {
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Array is too large to be encoded as calldata. " ) ;
text = R " (
contract C {
function f ( uint [ 85678901234 ] a ) internal {
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
text = R " (
contract C {
function f ( uint [ 85678901234 ] a ) {
}
}
) " ;
2017-07-13 15:02:10 +00:00
CHECK_ERROR ( text , TypeError , " Array is too large to be encoded as calldata. " ) ;
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 {
function f ( ) {
string memory x = " abc " ;
x ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
text = R " (
contract C {
function f ( ) {
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 {
function f ( ) {
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 {
function f ( ) {
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 {
struct S { }
modifier m ( S storage x ) {
x ;
_ ;
}
}
) " ;
CHECK_SUCCESS_NO_WARNINGS ( text ) ;
}
2017-02-05 19:06:04 +00:00
BOOST_AUTO_TEST_CASE ( using_this_in_constructor )
{
char const * text = R " (
contract C {
function C ( ) {
this . f ( ) ;
}
function f ( ) {
}
}
) " ;
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 ;
function f ( ) {
m ( 1 ) = 2 ;
}
}
) " ;
CHECK_ERROR_ALLOW_MULTI ( text , TypeError , " is not callable " ) ;
}
2017-07-31 19:54:54 +00:00
BOOST_AUTO_TEST_CASE ( builtin_reject_gas )
{
char const * text = R " (
contract C {
function f ( ) {
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 {
function f ( ) {
sha256 . gas ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" gas \" not found or not visible after argument-dependent lookup " ) ;
text = R " (
contract C {
function f ( ) {
ripemd160 . gas ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" gas \" not found or not visible after argument-dependent lookup " ) ;
text = R " (
contract C {
function f ( ) {
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
}
BOOST_AUTO_TEST_CASE ( builtin_reject_value )
{
char const * text = R " (
contract C {
function f ( ) {
keccak256 . value ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" value \" not found or not visible after argument-dependent lookup " ) ;
text = R " (
contract C {
function f ( ) {
sha256 . value ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" value \" not found or not visible after argument-dependent lookup " ) ;
text = R " (
contract C {
function f ( ) {
ripemd160 . value ( ) ;
}
}
) " ;
CHECK_ERROR ( text , TypeError , " Member \" value \" not found or not visible after argument-dependent lookup " ) ;
text = R " (
contract C {
function f ( ) {
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 {
function f ( ) ;
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-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. " ) ;
2017-08-08 13:41:46 +00:00
// text = R"(
2017-08-10 16:09:44 +00:00
// pragma experimental __test;
// pragma experimental __test;
2017-08-08 13:41:46 +00:00
// )";
2017-08-10 16:09:44 +00:00
// CHECK_ERROR_ALLOW_MULTI(text, SyntaxError, "Duplicate experimental feature name.");
2017-08-08 13:41:46 +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