Skip to content

Commit 6b6e163

Browse files
committed
Tests.
1 parent ad13062 commit 6b6e163

25 files changed

+354
-14
lines changed

test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ set(libsolidity_sources
8383
libsolidity/InlineAssembly.cpp
8484
libsolidity/LibSolc.cpp
8585
libsolidity/Metadata.cpp
86+
libsolidity/MemoryGuardTest.cpp
87+
libsolidity/MemoryGuardTest.h
8688
libsolidity/SemanticTest.cpp
8789
libsolidity/SemanticTest.h
8890
libsolidity/SemVerMatcher.cpp

test/InteractiveTests.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <test/libsolidity/ABIJsonTest.h>
2323
#include <test/libsolidity/ASTJSONTest.h>
2424
#include <test/libsolidity/GasTest.h>
25+
#include <test/libsolidity/MemoryGuardTest.h>
2526
#include <test/libsolidity/SyntaxTest.h>
2627
#include <test/libsolidity/SemanticTest.h>
2728
#include <test/libsolidity/SMTCheckerTest.h>
@@ -74,6 +75,7 @@ Testsuite const g_interactiveTestsuites[] = {
7475
{"JSON ABI", "libsolidity", "ABIJson", false, false, &ABIJsonTest::create},
7576
{"SMT Checker", "libsolidity", "smtCheckerTests", true, false, &SMTCheckerTest::create},
7677
{"Gas Estimates", "libsolidity", "gasTests", false, false, &GasTest::create},
78+
{"Memory Guard Tests", "libsolidity", "memoryGuardTests", false, false, &MemoryGuardTest::create},
7779
{"Ewasm Translation", "libyul", "ewasmTranslationTests", false, false, &yul::test::EwasmTranslationTest::create}
7880
};
7981

test/cmdlineTests/constant_optimizer_yul/output

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,23 @@ object "C_12" {
1111
code {
1212
{
1313
/// @src 0:61:418 "contract C {..."
14-
mstore(64, 128)
14+
let _1 := memoryguard(0x80)
15+
mstore(64, _1)
1516
if callvalue() { revert(0, 0) }
1617
/// @src 0:103:238 "assembly {..."
1718
sstore(0, shl(180, 1))
1819
/// @src 0:61:418 "contract C {..."
19-
let _1 := datasize("C_12_deployed")
20-
codecopy(128, dataoffset("C_12_deployed"), _1)
21-
return(128, _1)
20+
let _2 := datasize("C_12_deployed")
21+
codecopy(_1, dataoffset("C_12_deployed"), _2)
22+
return(_1, _2)
2223
}
2324
}
2425
/// @use-src 0:"constant_optimizer_yul/input.sol"
2526
object "C_12_deployed" {
2627
code {
2728
{
2829
/// @src 0:61:418 "contract C {..."
29-
mstore(64, 128)
30+
mstore(64, memoryguard(0x80))
3031
if callvalue() { revert(0, 0) }
3132
/// @src 0:279:410 "assembly {..."
3233
sstore(0, 0x1000000000000000000000000000000000000000000000)

test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/input.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ pragma solidity >=0.0.0;
33
pragma abicoder v2;
44

55
contract D {
6-
constructor() { assembly {}}
6+
constructor() { assembly { mstore(0,0) } }
77
function f() public pure {}
88
}

test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ Optimized IR:
1010
object "D_12" {
1111
code {
1212
{
13-
/// @src 0:82:161 "contract D {..."
13+
/// @src 0:82:175 "contract D {..."
1414
mstore(64, 128)
1515
if callvalue() { revert(0, 0) }
16+
/// @src 0:115:139 "assembly { mstore(0,0) }"
17+
mstore(0, 0)
18+
/// @src 0:82:175 "contract D {..."
1619
let _1 := datasize("D_12_deployed")
1720
codecopy(128, dataoffset("D_12_deployed"), _1)
1821
return(128, _1)
@@ -22,7 +25,7 @@ object "D_12" {
2225
object "D_12_deployed" {
2326
code {
2427
{
25-
/// @src 0:82:161 "contract D {..."
28+
/// @src 0:82:175 "contract D {..."
2629
let _1 := memoryguard(0x80)
2730
mstore(64, _1)
2831
if iszero(lt(calldatasize(), 4))

test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/input.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ pragma abicoder v2;
44

55
contract D {
66
function f() public pure {
7-
assembly {}
7+
assembly { mstore(0,0) }
88
}
99
}

test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Optimized IR:
1010
object "D_8" {
1111
code {
1212
{
13-
/// @src 0:82:153 "contract D {..."
13+
/// @src 0:82:166 "contract D {..."
1414
let _1 := memoryguard(0x80)
1515
mstore(64, _1)
1616
if callvalue() { revert(0, 0) }
@@ -23,7 +23,7 @@ object "D_8" {
2323
object "D_8_deployed" {
2424
code {
2525
{
26-
/// @src 0:82:153 "contract D {..."
26+
/// @src 0:82:166 "contract D {..."
2727
mstore(64, 128)
2828
if iszero(lt(calldatasize(), 4))
2929
{
@@ -32,6 +32,8 @@ object "D_8" {
3232
{
3333
if callvalue() { revert(_1, _1) }
3434
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
35+
/// @src 0:134:158 "assembly { mstore(0,0) }"
36+
mstore(/** @src 0:82:166 "contract D {..." */ _1, _1)
3537
return(128, _1)
3638
}
3739
}

test/libsolidity/MemoryGuardTest.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
This file is part of solidity.
3+
4+
solidity is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation, either version 3 of the License, or
7+
(at your option) any later version.
8+
9+
solidity is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with solidity. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
// SPDX-License-Identifier: GPL-3.0
18+
19+
#include <test/libsolidity/MemoryGuardTest.h>
20+
21+
#include <test/libyul/Common.h>
22+
#include <libsolidity/codegen/ir/Common.h>
23+
#include <libsolutil/Algorithms.h>
24+
#include <libyul/Object.h>
25+
#include <libyul/backends/evm/EVMDialect.h>
26+
#include <libyul/optimiser/FunctionCallFinder.h>
27+
#include <fstream>
28+
#include <memory>
29+
#include <stdexcept>
30+
31+
using namespace std;
32+
using namespace solidity;
33+
using namespace solidity::util;
34+
using namespace solidity::util::formatting;
35+
using namespace solidity::langutil;
36+
using namespace solidity::frontend;
37+
using namespace solidity::frontend::test;
38+
using namespace yul;
39+
40+
TestCase::TestResult MemoryGuardTest::run(ostream& _stream, string const& _linePrefix, bool _formatted)
41+
{
42+
compiler().reset();
43+
compiler().setSources(StringMap{{"", m_source}});
44+
compiler().setViaIR(true);
45+
compiler().setOptimiserSettings(OptimiserSettings::none());
46+
if (!compiler().compile())
47+
return TestResult::FatalError;
48+
49+
m_obtainedResult.clear();
50+
for (string contractName: compiler().contractNames())
51+
{
52+
ErrorList errors;
53+
auto [object, analysisInfo] = yul::test::parse(
54+
compiler().yulIR(contractName),
55+
EVMDialect::strictAssemblyForEVMObjects({}),
56+
errors
57+
);
58+
59+
if (!object || !analysisInfo || Error::containsErrors(errors))
60+
{
61+
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing IR." << endl;
62+
return TestResult::FatalError;
63+
}
64+
65+
auto handleObject = [&](std::string const& _kind, Object const& _object) {
66+
m_obtainedResult += contractName + "(" + _kind + ") " + (FunctionCallFinder::run(
67+
*_object.code,
68+
"memoryguard"_yulstring
69+
).empty() ? "false" : "true") + "\n";
70+
};
71+
handleObject("creation", *object);
72+
size_t deployedIndex = object->subIndexByName.at(
73+
YulString(IRNames::deployedObject(compiler().contractDefinition(contractName)))
74+
);
75+
handleObject("runtime", dynamic_cast<Object const&>(*object->subObjects[deployedIndex]));
76+
}
77+
return checkResult(_stream, _linePrefix, _formatted);
78+
}

test/libsolidity/MemoryGuardTest.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
This file is part of solidity.
3+
4+
solidity is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation, either version 3 of the License, or
7+
(at your option) any later version.
8+
9+
solidity is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with solidity. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
// SPDX-License-Identifier: GPL-3.0
18+
19+
#pragma once
20+
21+
#include <test/libsolidity/AnalysisFramework.h>
22+
#include <test/TestCase.h>
23+
#include <test/CommonSyntaxTest.h>
24+
#include <liblangutil/Exceptions.h>
25+
#include <libsolutil/AnsiColorized.h>
26+
27+
#include <iosfwd>
28+
#include <string>
29+
#include <vector>
30+
#include <utility>
31+
32+
namespace solidity::frontend::test
33+
{
34+
35+
using solidity::test::SyntaxTestError;
36+
37+
class MemoryGuardTest: public AnalysisFramework, public TestCase
38+
{
39+
public:
40+
static std::unique_ptr<TestCase> create(Config const& _config)
41+
{
42+
return std::make_unique<MemoryGuardTest>(_config.filename);
43+
}
44+
MemoryGuardTest(std::string const& _filename): TestCase(_filename)
45+
{
46+
m_source = m_reader.source();
47+
m_expectation = m_reader.simpleExpectations();
48+
}
49+
50+
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false) override;
51+
};
52+
53+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
contract C {
2+
constructor() {
3+
uint256 x;
4+
assembly { x := 0 }
5+
f();
6+
}
7+
function f() internal pure {
8+
/// @solidity memory-safe-assembly
9+
assembly { mstore(0, 0) }
10+
}
11+
function g() public pure {
12+
assembly { mstore(0, 0) }
13+
}
14+
}
15+
// ----
16+
// :C(creation) true
17+
// :C(runtime) false

0 commit comments

Comments
 (0)