13
13
*/
14
14
15
15
#include < test/libsolidity/SemanticTest.h>
16
+ #include < test/libsolidity/util/BytesUtils.h>
16
17
#include < libsolutil/Whiskers.h>
17
18
#include < libyul/Exceptions.h>
18
19
#include < test/Common.h>
@@ -47,6 +48,15 @@ SemanticTest::SemanticTest(string const& _filename, langutil::EVMVersion _evmVer
47
48
m_lineOffset(m_reader.lineNumber()),
48
49
m_enforceViaYul(enforceViaYul)
49
50
{
51
+ using namespace std ::placeholders;
52
+ m_builtins
53
+ = {{" smoke" ,
54
+ {
55
+ {" test0()" , std::bind (&SemanticTest::builtinSmokeTest, this , _1)},
56
+ {" test1(uint256)" , std::bind (&SemanticTest::builtinSmokeTest, this , _1)},
57
+ {" test2(uint256,uint256)" , std::bind (&SemanticTest::builtinSmokeTest, this , _1)},
58
+ }}};
59
+
50
60
string choice = m_reader.stringSetting (" compileViaYul" , " default" );
51
61
if (choice == " also" )
52
62
{
@@ -197,6 +207,15 @@ TestCase::TestResult SemanticTest::runTest(ostream& _stream, string const& _line
197
207
bytes output;
198
208
if (test.call ().kind == FunctionCall::Kind::LowLevel)
199
209
output = callLowLevel (test.call ().arguments .rawBytes (), test.call ().value .value );
210
+ else if (test.call ().kind == FunctionCall::Kind::Builtin)
211
+ {
212
+ std::vector<string> builtinPath;
213
+ boost::split (builtinPath, test.call ().signature , boost::is_any_of (" ." ));
214
+ assert (builtinPath.size () == 2 );
215
+ auto builtin = m_builtins[builtinPath.front ()][builtinPath.back ()];
216
+ output = builtin (test.call ());
217
+ test.setFailure (output.empty ());
218
+ }
200
219
else
201
220
{
202
221
soltestAssert (
@@ -212,14 +231,33 @@ TestCase::TestResult SemanticTest::runTest(ostream& _stream, string const& _line
212
231
);
213
232
}
214
233
215
- bool outputMismatch = (output != test.call ().expectations .rawBytes ());
216
- // Pre byzantium, it was not possible to return failure data, so we disregard
217
- // output mismatch for those EVM versions.
218
- if (test.call ().expectations .failure && !m_transactionSuccessful && !m_evmVersion.supportsReturndata ())
219
- outputMismatch = false ;
220
- if (m_transactionSuccessful != !test.call ().expectations .failure || outputMismatch)
221
- success = false ;
234
+ bytes expectationOutput;
235
+ if (test.call ().expectations .builtin )
236
+ {
237
+ std::vector<string> builtinPath;
238
+ boost::split (builtinPath, test.call ().expectations .builtin ->signature , boost::is_any_of (" ." ));
239
+ assert (builtinPath.size () == 2 );
240
+ auto builtin = m_builtins[builtinPath.front ()][builtinPath.back ()];
241
+ expectationOutput = builtin (*test.call ().expectations .builtin );
242
+ }
243
+ else
244
+ expectationOutput = test.call ().expectations .rawBytes ();
222
245
246
+ bool outputMismatch = (output != expectationOutput);
247
+ if (test.call ().kind == FunctionCall::Kind::Builtin)
248
+ {
249
+ if (outputMismatch)
250
+ success = false ;
251
+ }
252
+ else
253
+ {
254
+ // Pre byzantium, it was not possible to return failure data, so we disregard
255
+ // output mismatch for those EVM versions.
256
+ if (test.call ().expectations .failure && !m_transactionSuccessful && !m_evmVersion.supportsReturndata ())
257
+ outputMismatch = false ;
258
+ if (m_transactionSuccessful != !test.call ().expectations .failure || outputMismatch)
259
+ success = false ;
260
+ }
223
261
test.setFailure (!m_transactionSuccessful);
224
262
test.setRawBytes (std::move (output));
225
263
test.setContractABI (m_compiler.contractABI (m_compiler.lastContractName ()));
@@ -340,13 +378,26 @@ void SemanticTest::printUpdatedSettings(ostream& _stream, string const& _linePre
340
378
341
379
void SemanticTest::parseExpectations (istream& _stream)
342
380
{
343
- TestFileParser parser{_stream};
381
+ TestFileParser parser{_stream, & this -> m_builtins };
344
382
auto functionCalls = parser.parseFunctionCalls (m_lineOffset);
345
383
std::move (functionCalls.begin (), functionCalls.end (), back_inserter (m_tests));
346
384
}
347
385
348
- bool SemanticTest::deploy (string const & _contractName, u256 const & _value, bytes const & _arguments, map<string, solidity::test::Address> const & _libraries)
386
+ bool SemanticTest::deploy (
387
+ string const & _contractName,
388
+ u256 const & _value,
389
+ bytes const & _arguments,
390
+ map<string, solidity::test::Address> const & _libraries)
349
391
{
350
392
auto output = compileAndRunWithoutCheck (m_sources.sources , _value, _contractName, _arguments, _libraries);
351
393
return !output.empty () && m_transactionSuccessful;
352
394
}
395
+
396
+ bytes SemanticTest::builtinSmokeTest (FunctionCall const & call)
397
+ {
398
+ // This function is only used in test/libsolidity/semanticTests/builtins/smoke.sol.
399
+ bytes result;
400
+ for (const auto & parameter : call.arguments .parameters )
401
+ result += util::toBigEndian (u256{util::fromHex (parameter.rawString )});
402
+ return result;
403
+ }
0 commit comments