2016-02-22 01:13:41 +00:00
/*
2016-11-18 23:13:20 +00:00
This file is part of solidity .
2016-02-22 01:13:41 +00:00
2016-11-18 23:13:20 +00:00
solidity is free software : you can redistribute it and / or modify
2016-02-22 01:13:41 +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 ,
2016-02-22 01:13:41 +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/>.
2016-02-22 01:13:41 +00:00
*/
/**
* @ author Christian < c @ ethdev . com >
* @ date 2016
* Unit tests for inline assembly .
*/
2020-01-14 16:48:17 +00:00
# include <test/Common.h>
2017-02-17 15:04:42 +00:00
2019-02-13 11:07:20 +00:00
# include <test/libsolidity/ErrorCheck.h>
# include <libsolidity/ast/AST.h>
# include <libyul/AssemblyStack.h>
2018-11-14 13:59:30 +00:00
# include <liblangutil/Scanner.h>
# include <liblangutil/Exceptions.h>
2019-05-22 22:25:39 +00:00
# include <liblangutil/SourceReferenceFormatter.h>
2019-02-13 11:07:20 +00:00
2017-02-17 15:04:42 +00:00
# include <libevmasm/Assembly.h>
2017-04-21 22:05:12 +00:00
# include <boost/algorithm/string/replace.hpp>
2020-01-14 14:55:31 +00:00
# include <boost/test/unit_test.hpp>
2017-02-17 15:04:42 +00:00
# include <memory>
2019-10-28 10:39:30 +00:00
# include <optional>
# include <string>
2016-02-22 01:13:41 +00:00
using namespace std ;
2019-12-23 15:50:30 +00:00
using namespace solidity : : langutil ;
using namespace solidity : : yul ;
2016-02-22 01:13:41 +00:00
2019-12-23 15:50:30 +00:00
namespace solidity : : frontend : : test
2016-02-22 01:13:41 +00:00
{
namespace
{
2019-10-28 10:39:30 +00:00
std : : optional < Error > parseAndReturnFirstError (
2017-05-31 10:39:50 +00:00
string const & _source ,
bool _assemble = false ,
bool _allowWarnings = true ,
2018-01-06 00:24:45 +00:00
AssemblyStack : : Language _language = AssemblyStack : : Language : : Assembly ,
2017-05-31 10:39:50 +00:00
AssemblyStack : : Machine _machine = AssemblyStack : : Machine : : EVM
)
2016-02-22 01:13:41 +00:00
{
2020-01-14 16:48:17 +00:00
AssemblyStack stack ( solidity : : test : : CommonOptions : : get ( ) . evmVersion ( ) , _language , solidity : : frontend : : OptimiserSettings : : none ( ) ) ;
2017-02-17 15:04:42 +00:00
bool success = false ;
2016-02-22 01:13:41 +00:00
try
{
2017-05-31 10:39:50 +00:00
success = stack . parseAndAnalyze ( " " , _source ) ;
2017-02-17 15:04:42 +00:00
if ( success & & _assemble )
2019-03-27 11:49:50 +00:00
stack . assemble ( _machine ) ;
2016-02-22 01:13:41 +00:00
}
2017-02-20 10:57:50 +00:00
catch ( FatalError const & )
2016-02-22 01:13:41 +00:00
{
2017-02-17 15:04:42 +00:00
BOOST_FAIL ( " Fatal error leaked. " ) ;
success = false ;
2016-02-22 01:13:41 +00:00
}
2017-06-28 17:30:13 +00:00
shared_ptr < Error const > error ;
for ( auto const & e : stack . errors ( ) )
2017-02-17 15:04:42 +00:00
{
2017-06-28 17:30:13 +00:00
if ( _allowWarnings & & e - > type ( ) = = Error : : Type : : Warning )
continue ;
if ( error )
2019-05-22 22:25:39 +00:00
{
string errors ;
for ( auto const & err : stack . errors ( ) )
errors + = SourceReferenceFormatter : : formatErrorInformation ( * err ) ;
BOOST_FAIL ( " Found more than one error: \n " + errors ) ;
}
2017-06-28 17:30:13 +00:00
error = e ;
2017-02-17 15:04:42 +00:00
}
2017-06-28 17:30:13 +00:00
if ( ! success )
BOOST_REQUIRE ( error ) ;
if ( error )
return * error ;
2017-02-17 15:04:42 +00:00
return { } ;
}
2016-02-22 01:13:41 +00:00
2017-05-31 10:39:50 +00:00
bool successParse (
string const & _source ,
bool _assemble = false ,
bool _allowWarnings = true ,
2018-01-06 00:24:45 +00:00
AssemblyStack : : Language _language = AssemblyStack : : Language : : Assembly ,
2017-05-31 10:39:50 +00:00
AssemblyStack : : Machine _machine = AssemblyStack : : Machine : : EVM
)
2017-02-17 15:04:42 +00:00
{
2018-01-06 00:24:45 +00:00
return ! parseAndReturnFirstError ( _source , _assemble , _allowWarnings , _language , _machine ) ;
2016-02-22 01:13:41 +00:00
}
2018-01-06 00:24:45 +00:00
bool successAssemble ( string const & _source , bool _allowWarnings = true , AssemblyStack : : Language _language = AssemblyStack : : Language : : Assembly )
2016-03-01 21:56:39 +00:00
{
2018-01-06 00:24:45 +00:00
return
successParse ( _source , true , _allowWarnings , _language , AssemblyStack : : Machine : : EVM ) & &
successParse ( _source , true , _allowWarnings , _language , AssemblyStack : : Machine : : EVM15 ) ;
2016-03-01 21:56:39 +00:00
}
2018-01-06 00:24:45 +00:00
Error expectError (
std : : string const & _source ,
bool _assemble ,
bool _allowWarnings = false ,
AssemblyStack : : Language _language = AssemblyStack : : Language : : Assembly
)
2017-02-17 15:04:42 +00:00
{
2018-01-06 00:24:45 +00:00
auto error = parseAndReturnFirstError ( _source , _assemble , _allowWarnings , _language ) ;
2017-02-17 15:04:42 +00:00
BOOST_REQUIRE ( error ) ;
return * error ;
}
2017-06-28 17:30:13 +00:00
void parsePrintCompare ( string const & _source , bool _canWarn = false )
2017-02-14 14:40:58 +00:00
{
2020-01-14 16:48:17 +00:00
AssemblyStack stack ( solidity : : test : : CommonOptions : : get ( ) . evmVersion ( ) , AssemblyStack : : Language : : Assembly , OptimiserSettings : : none ( ) ) ;
2017-05-31 10:39:50 +00:00
BOOST_REQUIRE ( stack . parseAndAnalyze ( " " , _source ) ) ;
2017-06-28 17:30:13 +00:00
if ( _canWarn )
BOOST_REQUIRE ( Error : : containsOnlyWarnings ( stack . errors ( ) ) ) ;
else
BOOST_REQUIRE ( stack . errors ( ) . empty ( ) ) ;
2018-11-07 11:01:43 +00:00
string expectation = " object \" object \" { \n code " + boost : : replace_all_copy ( _source , " \n " , " \n " ) + " \n } \n " ;
BOOST_CHECK_EQUAL ( stack . print ( ) , expectation ) ;
2017-02-14 14:40:58 +00:00
}
2016-02-22 01:13:41 +00:00
}
2018-01-06 00:24:45 +00:00
# define CHECK_ERROR_LANG(text, assemble, typ, substring, warnings, language) \
2017-02-17 15:04:42 +00:00
do \
{ \
2018-01-06 00:24:45 +00:00
Error err = expectError ( ( text ) , ( assemble ) , warnings , ( language ) ) ; \
2017-02-17 15:04:42 +00:00
BOOST_CHECK ( err . type ( ) = = ( Error : : Type : : typ ) ) ; \
BOOST_CHECK ( searchErrorMessage ( err , ( substring ) ) ) ; \
} while ( 0 )
2018-01-06 00:24:45 +00:00
# define CHECK_ERROR(text, assemble, typ, substring, warnings) \
CHECK_ERROR_LANG ( text , assemble , typ , substring , warnings , AssemblyStack : : Language : : Assembly )
2017-02-17 15:04:42 +00:00
# define CHECK_PARSE_ERROR(text, type, substring) \
2017-06-28 17:30:13 +00:00
CHECK_ERROR ( text , false , type , substring , false )
# define CHECK_PARSE_WARNING(text, type, substring) \
CHECK_ERROR ( text , false , type , substring , false )
2017-02-17 15:04:42 +00:00
# define CHECK_ASSEMBLE_ERROR(text, type, substring) \
2017-06-28 17:30:13 +00:00
CHECK_ERROR ( text , true , type , substring , false )
2017-02-17 15:04:42 +00:00
2018-01-06 00:24:45 +00:00
# define CHECK_STRICT_ERROR(text, type, substring) \
CHECK_ERROR_LANG ( text , false , type , substring , false , AssemblyStack : : Language : : StrictAssembly )
# define CHECK_STRICT_WARNING(text, type, substring) \
CHECK_ERROR ( text , false , type , substring , false , AssemblyStack : : Language : : StrictAssembly )
# define SUCCESS_STRICT(text) \
do { successParse ( ( text ) , false , false , AssemblyStack : : Language : : StrictAssembly ) ; } while ( false )
2017-02-17 15:04:42 +00:00
2016-02-22 01:13:41 +00:00
BOOST_AUTO_TEST_SUITE ( SolidityInlineAssembly )
2017-02-14 14:40:58 +00:00
BOOST_AUTO_TEST_SUITE ( Parsing )
2016-02-22 01:13:41 +00:00
BOOST_AUTO_TEST_CASE ( smoke_test )
{
BOOST_CHECK ( successParse ( " { } " ) ) ;
}
2018-02-20 17:39:00 +00:00
BOOST_AUTO_TEST_CASE ( surplus_input )
{
2018-05-02 18:49:36 +00:00
CHECK_PARSE_ERROR ( " { } { } " , ParserError , " Expected end of source but got '{' " ) ;
2018-02-20 17:39:00 +00:00
}
2016-02-22 01:13:41 +00:00
BOOST_AUTO_TEST_CASE ( simple_instructions )
{
2019-09-10 11:35:55 +00:00
BOOST_CHECK ( successParse ( " { let y := mul(0x10, mul(0x20, mload(0x40)))} " ) ) ;
2016-02-22 01:13:41 +00:00
}
2018-04-16 22:46:14 +00:00
BOOST_AUTO_TEST_CASE ( selfdestruct )
2016-10-05 11:00:36 +00:00
{
2019-09-10 11:35:55 +00:00
BOOST_CHECK ( successParse ( " { selfdestruct(0x02) } " ) ) ;
2016-10-05 11:00:36 +00:00
}
2016-04-05 12:57:40 +00:00
BOOST_AUTO_TEST_CASE ( keywords )
{
2019-09-10 11:35:55 +00:00
BOOST_CHECK ( successParse ( " { return (byte(1, 2), 2) pop(address()) } " ) ) ;
2016-04-05 12:57:40 +00:00
}
2016-02-22 01:13:41 +00:00
BOOST_AUTO_TEST_CASE ( constants )
{
2019-09-10 11:35:55 +00:00
BOOST_CHECK ( successParse ( " { pop(mul(7, 8)) } " ) ) ;
2016-02-22 01:13:41 +00:00
}
BOOST_AUTO_TEST_CASE ( blocks )
{
BOOST_CHECK ( successParse ( " { let x := 7 { let y := 3 } { let z := 2 } } " ) ) ;
}
2017-08-21 10:08:29 +00:00
BOOST_AUTO_TEST_CASE ( number_literals )
{
BOOST_CHECK ( successParse ( " { let x := 1 } " ) ) ;
CHECK_PARSE_ERROR ( " { let x := .1 } " , ParserError , " Invalid number literal. " ) ;
CHECK_PARSE_ERROR ( " { let x := 1e5 } " , ParserError , " Invalid number literal. " ) ;
CHECK_PARSE_ERROR ( " { let x := 67.235 } " , ParserError , " Invalid number literal. " ) ;
2018-01-04 23:25:41 +00:00
CHECK_STRICT_ERROR ( " { let x := 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff } " , TypeError , " Number literal too large (> 256 bits) " ) ;
2017-08-21 10:08:29 +00:00
}
2017-02-17 15:05:22 +00:00
BOOST_AUTO_TEST_CASE ( opcode_for_functions )
{
2019-05-22 22:25:39 +00:00
CHECK_PARSE_ERROR ( " { function gas() { } } " , ParserError , " Cannot use builtin " ) ;
2017-02-17 15:05:22 +00:00
}
BOOST_AUTO_TEST_CASE ( opcode_for_function_args )
{
2019-05-22 22:25:39 +00:00
CHECK_PARSE_ERROR ( " { function f(gas) { } } " , ParserError , " Cannot use builtin " ) ;
CHECK_PARSE_ERROR ( " { function f() -> gas { } } " , ParserError , " Cannot use builtin " ) ;
2017-02-17 15:05:22 +00:00
}
BOOST_AUTO_TEST_CASE ( variable_access_cross_functions )
{
2019-09-10 11:35:55 +00:00
CHECK_PARSE_ERROR ( " { let x := 2 function g() { pop(x) } } " , DeclarationError , " Identifier not found. " ) ;
2017-02-01 20:20:21 +00:00
}
2017-05-06 14:49:22 +00:00
BOOST_AUTO_TEST_CASE ( invalid_tuple_assignment )
{
2018-12-04 10:22:49 +00:00
CHECK_PARSE_ERROR ( " { let x, y := 1 } " , DeclarationError , " Variable count mismatch: 2 variables and 1 values " ) ;
2017-05-06 14:49:22 +00:00
}
2017-05-24 12:23:53 +00:00
BOOST_AUTO_TEST_CASE ( instruction_too_few_arguments )
{
2019-05-22 22:25:39 +00:00
CHECK_PARSE_ERROR ( " { pop(mul()) } " , TypeError , " Function expects 2 arguments but got 0. " ) ;
CHECK_PARSE_ERROR ( " { pop(mul(1)) } " , TypeError , " Function expects 2 arguments but got 1. " ) ;
2017-05-24 12:23:53 +00:00
}
BOOST_AUTO_TEST_CASE ( instruction_too_many_arguments )
{
2019-05-22 22:25:39 +00:00
CHECK_PARSE_ERROR ( " { pop(mul(1, 2, 3)) } " , TypeError , " Function expects 2 arguments but got 3 " ) ;
2017-05-24 12:23:53 +00:00
}
2017-08-21 10:29:04 +00:00
BOOST_AUTO_TEST_CASE ( recursion_depth )
{
string input ;
for ( size_t i = 0 ; i < 20000 ; i + + )
input + = " { " ;
input + = " let x := 0 " ;
for ( size_t i = 0 ; i < 20000 ; i + + )
input + = " } " ;
CHECK_PARSE_ERROR ( input , ParserError , " recursion " ) ;
}
2017-05-19 16:06:26 +00:00
BOOST_AUTO_TEST_CASE ( multiple_assignment )
{
2019-02-18 14:07:15 +00:00
CHECK_PARSE_ERROR ( " { let x function f() -> a, b {} 123, x := f() } " , ParserError , " Variable name must precede \" , \" in multiple assignment. " ) ;
CHECK_PARSE_ERROR ( " { let x function f() -> a, b {} x, 123 := f() } " , ParserError , " Variable name must precede \" := \" in assignment. " ) ;
2017-08-21 10:29:04 +00:00
2017-05-19 16:06:26 +00:00
/// NOTE: Travis hiccups if not having a variable
char const * text = R " (
{
function f ( a ) - > r1 , r2 {
r1 : = a
r2 : = 7
}
let x : = 9
let y : = 2
x , y : = f ( x )
}
) " ;
BOOST_CHECK ( successParse ( text ) ) ;
}
2017-08-21 10:29:04 +00:00
2017-02-14 14:40:58 +00:00
BOOST_AUTO_TEST_SUITE_END ( )
BOOST_AUTO_TEST_SUITE ( Printing )
BOOST_AUTO_TEST_CASE ( print_smoke )
{
2019-05-08 10:41:19 +00:00
parsePrintCompare ( " { } " ) ;
2017-02-14 14:40:58 +00:00
}
BOOST_AUTO_TEST_CASE ( print_instructions )
{
2019-09-10 11:35:55 +00:00
parsePrintCompare ( " { pop(7) } " ) ;
2017-02-14 14:40:58 +00:00
}
BOOST_AUTO_TEST_CASE ( print_subblock )
{
2019-09-10 11:35:55 +00:00
parsePrintCompare ( " { { pop(7) } } " ) ;
2017-02-14 14:40:58 +00:00
}
BOOST_AUTO_TEST_CASE ( print_functional )
{
2019-05-08 10:41:19 +00:00
parsePrintCompare ( " { let x := mul(sload(0x12), 7) } " ) ;
2017-02-14 14:40:58 +00:00
}
BOOST_AUTO_TEST_CASE ( print_assignments )
{
2019-09-10 11:35:55 +00:00
parsePrintCompare ( " { \n let x := mul(2, 3) \n pop(7) \n x := add(1, 2) \n } " ) ;
2017-02-14 14:40:58 +00:00
}
2017-05-06 14:49:22 +00:00
BOOST_AUTO_TEST_CASE ( print_multi_assignments )
{
2019-05-08 10:41:19 +00:00
parsePrintCompare ( " { \n function f() -> x, y \n { } \n let x, y := f() \n } " ) ;
2017-05-06 14:49:22 +00:00
}
2017-02-14 14:40:58 +00:00
BOOST_AUTO_TEST_CASE ( print_string_literals )
{
2019-09-10 11:35:55 +00:00
parsePrintCompare ( " { let x := \" \\ n' \\ xab \\ x95 \\ \" \" } " ) ;
2017-02-14 14:40:58 +00:00
}
2017-02-15 14:21:11 +00:00
BOOST_AUTO_TEST_CASE ( print_string_literal_unicode )
{
2017-03-22 12:21:41 +00:00
string source = " { let x := \" \\ u1bac \" } " ;
2019-05-08 10:41:19 +00:00
string parsed = " object \" object \" { \n code { let x := \" \\ xe1 \\ xae \\ xac \" } \n } \n " ;
2020-01-14 16:48:17 +00:00
AssemblyStack stack ( solidity : : test : : CommonOptions : : get ( ) . evmVersion ( ) , AssemblyStack : : Language : : Assembly , OptimiserSettings : : none ( ) ) ;
2017-05-31 10:39:50 +00:00
BOOST_REQUIRE ( stack . parseAndAnalyze ( " " , source ) ) ;
2017-02-15 14:21:11 +00:00
BOOST_REQUIRE ( stack . errors ( ) . empty ( ) ) ;
2017-05-31 10:39:50 +00:00
BOOST_CHECK_EQUAL ( stack . print ( ) , parsed ) ;
2018-11-07 11:01:43 +00:00
2019-05-08 10:41:19 +00:00
string parsedInner = " { let x := \" \\ xe1 \\ xae \\ xac \" } " ;
2018-11-07 11:01:43 +00:00
parsePrintCompare ( parsedInner ) ;
2017-02-15 14:21:11 +00:00
}
2017-11-22 15:24:59 +00:00
BOOST_AUTO_TEST_CASE ( print_if )
{
2019-05-08 10:41:19 +00:00
parsePrintCompare ( " { if 2 { pop(mload(0)) } } " ) ;
2017-11-22 15:24:59 +00:00
}
2017-05-23 11:26:01 +00:00
BOOST_AUTO_TEST_CASE ( print_switch )
{
2019-05-08 10:41:19 +00:00
parsePrintCompare ( " { \n switch 42 \n case 1 { } \n case 2 { } \n default { } \n } " ) ;
2017-05-23 11:26:01 +00:00
}
2017-04-28 13:33:52 +00:00
BOOST_AUTO_TEST_CASE ( print_for )
{
2019-05-08 10:41:19 +00:00
parsePrintCompare ( " { \n let ret := 5 \n for { let i := 1 } lt(i, 15) { i := add(i, 1) } \n { ret := mul(ret, i) } \n } " ) ;
2017-04-28 13:33:52 +00:00
}
2017-02-14 15:08:33 +00:00
BOOST_AUTO_TEST_CASE ( function_definitions_multiple_args )
{
2019-05-08 10:41:19 +00:00
parsePrintCompare ( " { \n function f(a, d) \n { mstore(a, d) } \n function g(a, d) -> x, y \n { } \n } " ) ;
2017-02-14 15:08:33 +00:00
}
BOOST_AUTO_TEST_CASE ( function_calls )
{
2017-03-22 15:53:15 +00:00
string source = R " ({
function y ( )
2019-05-08 10:41:19 +00:00
{ }
2017-04-26 16:12:26 +00:00
function f ( a ) - > b
2019-05-08 10:41:19 +00:00
{ }
2017-03-22 15:53:15 +00:00
function g ( a , b , c )
2019-05-08 10:41:19 +00:00
{ }
2017-12-13 11:28:02 +00:00
g ( 1 , mul ( 2 , address ( ) ) , f ( mul ( 2 , caller ( ) ) ) )
2017-03-22 15:53:15 +00:00
y ( )
} ) " ;
boost : : replace_all ( source , " \t " , " " ) ;
parsePrintCompare ( source ) ;
2017-02-14 15:08:33 +00:00
}
2017-02-14 14:40:58 +00:00
BOOST_AUTO_TEST_SUITE_END ( )
BOOST_AUTO_TEST_SUITE ( Analysis )
2016-03-01 21:56:39 +00:00
BOOST_AUTO_TEST_CASE ( string_literals )
{
BOOST_CHECK ( successAssemble ( " { let x := \" 12345678901234567890123456789012 \" } " ) ) ;
}
BOOST_AUTO_TEST_CASE ( oversize_string_literals )
{
2017-02-20 10:42:23 +00:00
CHECK_ASSEMBLE_ERROR ( " { let x := \" 123456789012345678901234567890123 \" } " , TypeError , " String literal too long " ) ;
2016-03-01 21:56:39 +00:00
}
2016-10-07 23:03:56 +00:00
BOOST_AUTO_TEST_CASE ( magic_variables )
{
2019-09-10 11:35:55 +00:00
CHECK_ASSEMBLE_ERROR ( " { pop(this) } " , DeclarationError , " Identifier not found " ) ;
CHECK_ASSEMBLE_ERROR ( " { pop(ecrecover) } " , DeclarationError , " Identifier not found " ) ;
BOOST_CHECK ( successAssemble ( " { let ecrecover := 1 pop(ecrecover) } " ) ) ;
2016-10-07 23:03:56 +00:00
}
2017-04-11 17:24:38 +00:00
BOOST_AUTO_TEST_CASE ( stack_variables )
{
2019-09-10 11:35:55 +00:00
BOOST_CHECK ( successAssemble ( " { let y := 3 { let z := 2 { let x := y } } } " ) ) ;
2016-10-20 11:30:10 +00:00
}
2017-01-27 21:24:58 +00:00
BOOST_AUTO_TEST_CASE ( designated_invalid_instruction )
{
2019-09-10 11:35:55 +00:00
BOOST_CHECK ( successAssemble ( " { invalid() } " ) ) ;
2017-01-27 21:24:58 +00:00
}
2017-01-25 16:27:01 +00:00
BOOST_AUTO_TEST_CASE ( inline_assembly_shadowed_instruction_declaration )
2017-01-25 16:24:43 +00:00
{
2019-05-22 22:25:39 +00:00
CHECK_ASSEMBLE_ERROR ( " { let gas := 1 } " , ParserError , " Cannot use builtin " ) ;
2017-01-25 16:24:43 +00:00
}
2017-02-09 16:34:48 +00:00
BOOST_AUTO_TEST_CASE ( revert )
{
BOOST_CHECK ( successAssemble ( " { revert(0, 0) } " ) ) ;
}
2017-05-24 16:34:19 +00:00
BOOST_AUTO_TEST_CASE ( large_constant )
{
auto source = R " ({
switch mul ( 1 , 2 )
case 0x0000000000000000000000000000000000000000000000000000000026121ff0 {
}
} ) " ;
BOOST_CHECK ( successAssemble ( source ) ) ;
}
2017-05-30 09:29:15 +00:00
BOOST_AUTO_TEST_CASE ( keccak256 )
{
BOOST_CHECK ( successAssemble ( " { pop(keccak256(0, 0)) } " ) ) ;
}
2017-05-16 16:45:08 +00:00
BOOST_AUTO_TEST_CASE ( returndatasize )
2017-05-29 12:46:42 +00:00
{
2020-01-14 16:48:17 +00:00
if ( ! solidity : : test : : CommonOptions : : get ( ) . evmVersion ( ) . supportsReturndata ( ) )
2019-02-26 18:21:32 +00:00
return ;
2017-05-29 12:46:42 +00:00
BOOST_CHECK ( successAssemble ( " { let r := returndatasize() } " ) ) ;
}
2017-05-16 16:45:08 +00:00
BOOST_AUTO_TEST_CASE ( returndatacopy )
2017-05-29 12:46:42 +00:00
{
2020-01-14 16:48:17 +00:00
if ( ! solidity : : test : : CommonOptions : : get ( ) . evmVersion ( ) . supportsReturndata ( ) )
2019-02-26 18:21:32 +00:00
return ;
2019-09-10 11:35:55 +00:00
BOOST_CHECK ( successAssemble ( " { returndatacopy(0, 32, 64) } " ) ) ;
2017-05-29 12:46:42 +00:00
}
2017-06-08 14:44:03 +00:00
BOOST_AUTO_TEST_CASE ( staticcall )
{
2020-01-14 16:48:17 +00:00
if ( ! solidity : : test : : CommonOptions : : get ( ) . evmVersion ( ) . hasStaticCall ( ) )
2019-02-26 18:21:32 +00:00
return ;
2017-06-08 14:44:03 +00:00
BOOST_CHECK ( successAssemble ( " { pop(staticcall(10000, 0x123, 64, 0x10, 128, 0x10)) } " ) ) ;
}
BOOST_AUTO_TEST_CASE ( create2 )
{
2020-01-14 16:48:17 +00:00
if ( ! solidity : : test : : CommonOptions : : get ( ) . evmVersion ( ) . hasCreate2 ( ) )
2019-02-26 18:21:32 +00:00
return ;
2017-06-08 14:44:03 +00:00
BOOST_CHECK ( successAssemble ( " { pop(create2(10, 0x123, 32, 64)) } " ) ) ;
}
2018-02-27 11:09:22 +00:00
BOOST_AUTO_TEST_CASE ( shift )
{
2020-01-14 16:48:17 +00:00
if ( ! solidity : : test : : CommonOptions : : get ( ) . evmVersion ( ) . hasBitwiseShifting ( ) )
2019-02-26 18:21:32 +00:00
return ;
2018-02-27 11:09:22 +00:00
BOOST_CHECK ( successAssemble ( " { pop(shl(10, 32)) } " ) ) ;
BOOST_CHECK ( successAssemble ( " { pop(shr(10, 32)) } " ) ) ;
BOOST_CHECK ( successAssemble ( " { pop(sar(10, 32)) } " ) ) ;
}
BOOST_AUTO_TEST_CASE ( shift_constantinople_warning )
{
2020-01-14 16:48:17 +00:00
if ( solidity : : test : : CommonOptions : : get ( ) . evmVersion ( ) . hasBitwiseShifting ( ) )
2018-04-06 12:48:17 +00:00
return ;
2020-02-17 11:56:44 +00:00
CHECK_PARSE_WARNING ( " { shl(10, 32) } " , TypeError , " The \" shl \" instruction is only available for Constantinople-compatible VMs " ) ;
CHECK_PARSE_WARNING ( " { shr(10, 32) } " , TypeError , " The \" shr \" instruction is only available for Constantinople-compatible VMs " ) ;
CHECK_PARSE_WARNING ( " { sar(10, 32) } " , TypeError , " The \" sar \" instruction is only available for Constantinople-compatible VMs " ) ;
2018-02-27 11:09:22 +00:00
}
2019-09-10 11:35:55 +00:00
BOOST_AUTO_TEST_CASE ( jump_error )
2017-06-13 18:10:26 +00:00
{
2019-10-25 15:01:18 +00:00
CHECK_PARSE_WARNING ( " { jump(44) } " , DeclarationError , " Function not found. " ) ;
CHECK_PARSE_WARNING ( " { jumpi(44, 2) } " , DeclarationError , " Function not found. " ) ;
2017-06-13 18:10:26 +00:00
}
2016-02-22 01:13:41 +00:00
BOOST_AUTO_TEST_SUITE_END ( )
2017-02-14 14:40:58 +00:00
BOOST_AUTO_TEST_SUITE_END ( )
2016-02-22 01:13:41 +00:00
} // end namespaces