mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9373 from ethereum/develop
Merge develop into breaking.
This commit is contained in:
commit
9ef050af9a
@ -97,6 +97,7 @@ defaults:
|
||||
- test/tools/ossfuzz/strictasm_diff_ossfuzz
|
||||
- test/tools/ossfuzz/strictasm_opt_ossfuzz
|
||||
- test/tools/ossfuzz/yul_proto_diff_ossfuzz
|
||||
- test/tools/ossfuzz/yul_proto_diff_custom_mutate_ossfuzz
|
||||
- test/tools/ossfuzz/yul_proto_ossfuzz
|
||||
- test/tools/ossfuzz/sol_proto_ossfuzz
|
||||
|
||||
|
@ -54,7 +54,7 @@ get_logfile_basename() {
|
||||
echo -ne "${filename}"
|
||||
}
|
||||
|
||||
BOOST_TEST_ARGS="--color_output=no --show_progress=yes --logger=JUNIT,error,test_results/`get_logfile_basename`.xml"
|
||||
BOOST_TEST_ARGS="--color_output=no --show_progress=yes --logger=JUNIT,error,test_results/`get_logfile_basename`.xml ${BOOST_TEST_ARGS}"
|
||||
SOLTEST_ARGS="--evm-version=$EVM $SOLTEST_FLAGS"
|
||||
test "${OPTIMIZE}" = "1" && SOLTEST_ARGS="${SOLTEST_ARGS} --optimize"
|
||||
test "${ABI_ENCODER_V2}" = "1" && SOLTEST_ARGS="${SOLTEST_ARGS} --abiencoderv2"
|
||||
|
@ -30,7 +30,7 @@ REPODIR="$(realpath $(dirname $0)/..)"
|
||||
|
||||
for OPTIMIZE in 0 1; do
|
||||
for EVM in homestead byzantium constantinople petersburg istanbul; do
|
||||
EVM=$EVM OPTIMIZE=$OPTIMIZE ${REPODIR}/.circleci/soltest.sh
|
||||
EVM=$EVM OPTIMIZE=$OPTIMIZE BOOST_TEST_ARGS="-t !@nooptions" ${REPODIR}/.circleci/soltest.sh
|
||||
done
|
||||
done
|
||||
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -35,7 +35,7 @@ build/
|
||||
build*/
|
||||
emscripten_build/
|
||||
docs/_build
|
||||
docs/utils/__pycache__
|
||||
__pycache__
|
||||
docs/utils/*.pyc
|
||||
/deps/downloads/
|
||||
deps/install
|
||||
|
@ -26,7 +26,14 @@ Bugfixes:
|
||||
|
||||
### 0.6.12 (unreleased)
|
||||
|
||||
Compiler Features:
|
||||
* Code Generator: Evaluate ``keccak256`` of string literals at compile-time.
|
||||
|
||||
Bugfixes:
|
||||
* Type Checker: Fix overload resolution in combination with ``{value: ...}``.
|
||||
|
||||
Compiler Features:
|
||||
* Optimizer: Add rule to remove shifts inside the byte opcode.
|
||||
|
||||
|
||||
### 0.6.11 (2020-07-07)
|
||||
|
@ -571,6 +571,20 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart7(
|
||||
feasibilityFunction
|
||||
});
|
||||
|
||||
rules.push_back({
|
||||
Builtins::BYTE(A, Builtins::SHL(B, X)),
|
||||
[=]() -> Pattern { return Builtins::BYTE(A.d() + B.d() / 8, X); },
|
||||
false,
|
||||
[=] { return B.d() % 8 == 0 && A.d() <= 32 && B.d() <= 256; }
|
||||
});
|
||||
|
||||
rules.push_back({
|
||||
Builtins::BYTE(A, Builtins::SHR(B, X)),
|
||||
[=]() -> Pattern { return A.d() < B.d() / 8 ? Word(0) : Builtins::BYTE(A.d() - B.d() / 8, X); },
|
||||
false,
|
||||
[=] { return B.d() % 8 == 0 && A.d() < Pattern::WordSize / 8 && B.d() <= Pattern::WordSize; }
|
||||
});
|
||||
|
||||
return rules;
|
||||
}
|
||||
|
||||
|
@ -2404,6 +2404,8 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions)
|
||||
{
|
||||
solAssert(_functionCallOptions.options().size() == _functionCallOptions.names().size(), "Lengths of name & value arrays differ!");
|
||||
|
||||
_functionCallOptions.expression().annotation().arguments = _functionCallOptions.annotation().arguments;
|
||||
|
||||
_functionCallOptions.expression().accept(*this);
|
||||
|
||||
auto expressionFunctionType = dynamic_cast<FunctionType const*>(type(_functionCallOptions.expression()));
|
||||
|
@ -935,11 +935,6 @@ void ArrayUtils::clearStorageLoop(TypePointer _type) const
|
||||
}
|
||||
// stack: end_pos pos
|
||||
|
||||
// jump to and return from the loop to allow for duplicate code removal
|
||||
evmasm::AssemblyItem returnTag = _context.pushNewTag();
|
||||
_context << Instruction::SWAP2 << Instruction::SWAP1;
|
||||
|
||||
// stack: <return tag> end_pos pos
|
||||
evmasm::AssemblyItem loopStart = _context.appendJumpToNew();
|
||||
_context << loopStart;
|
||||
// check for loop condition
|
||||
@ -959,11 +954,8 @@ void ArrayUtils::clearStorageLoop(TypePointer _type) const
|
||||
_context.appendJumpTo(loopStart);
|
||||
// cleanup
|
||||
_context << zeroLoopEnd;
|
||||
_context << Instruction::POP << Instruction::SWAP1;
|
||||
// "return"
|
||||
_context << Instruction::JUMP;
|
||||
_context << Instruction::POP;
|
||||
|
||||
_context << returnTag;
|
||||
solAssert(_context.stackHeight() == stackHeightStart - 1, "");
|
||||
}
|
||||
);
|
||||
|
@ -792,20 +792,24 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
TypePointer const& argType = arguments.front()->annotation().type;
|
||||
solAssert(argType, "");
|
||||
arguments.front()->accept(*this);
|
||||
// Optimization: If type is bytes or string, then do not encode,
|
||||
// but directly compute keccak256 on memory.
|
||||
if (*argType == *TypeProvider::bytesMemory() || *argType == *TypeProvider::stringMemory())
|
||||
if (auto const* stringLiteral = dynamic_cast<StringLiteralType const*>(argType))
|
||||
// Optimization: Compute keccak256 on string literals at compile-time.
|
||||
m_context << u256(keccak256(stringLiteral->value()));
|
||||
else if (*argType == *TypeProvider::bytesMemory() || *argType == *TypeProvider::stringMemory())
|
||||
{
|
||||
// Optimization: If type is bytes or string, then do not encode,
|
||||
// but directly compute keccak256 on memory.
|
||||
ArrayUtils(m_context).retrieveLength(*TypeProvider::bytesMemory());
|
||||
m_context << Instruction::SWAP1 << u256(0x20) << Instruction::ADD;
|
||||
m_context << Instruction::KECCAK256;
|
||||
}
|
||||
else
|
||||
{
|
||||
utils().fetchFreeMemoryPointer();
|
||||
utils().packedEncode({argType}, TypePointers());
|
||||
utils().toSizeAfterFreeMemoryPointer();
|
||||
m_context << Instruction::KECCAK256;
|
||||
}
|
||||
m_context << Instruction::KECCAK256;
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::Log0:
|
||||
|
@ -1020,18 +1020,28 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
|
||||
ArrayType const* arrayType = TypeProvider::bytesMemory();
|
||||
|
||||
auto array = convert(*arguments[0], *arrayType);
|
||||
if (auto const* stringLiteral = dynamic_cast<StringLiteralType const*>(arguments.front()->annotation().type))
|
||||
{
|
||||
// Optimization: Compute keccak256 on string literals at compile-time.
|
||||
define(_functionCall) <<
|
||||
("0x" + keccak256(stringLiteral->value()).hex()) <<
|
||||
"\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
auto array = convert(*arguments[0], *arrayType);
|
||||
|
||||
define(_functionCall) <<
|
||||
"keccak256(" <<
|
||||
m_utils.arrayDataAreaFunction(*arrayType) <<
|
||||
"(" <<
|
||||
array.commaSeparatedList() <<
|
||||
"), " <<
|
||||
m_utils.arrayLengthFunction(*arrayType) <<
|
||||
"(" <<
|
||||
array.commaSeparatedList() <<
|
||||
"))\n";
|
||||
define(_functionCall) <<
|
||||
"keccak256(" <<
|
||||
m_utils.arrayDataAreaFunction(*arrayType) <<
|
||||
"(" <<
|
||||
array.commaSeparatedList() <<
|
||||
"), " <<
|
||||
m_utils.arrayLengthFunction(*arrayType) <<
|
||||
"(" <<
|
||||
array.commaSeparatedList() <<
|
||||
"))\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::ArrayPop:
|
||||
|
@ -10,16 +10,18 @@ git fetch origin
|
||||
error=0
|
||||
for new_proof in $(git diff origin/develop --name-only test/formal/)
|
||||
do
|
||||
set +e
|
||||
echo "Proving $new_proof..."
|
||||
output=$(python3 "$new_proof")
|
||||
result=$?
|
||||
set -e
|
||||
if [ -e "$new_proof" ]; then
|
||||
set +e
|
||||
echo "Proving $new_proof..."
|
||||
output=$(python3 "$new_proof")
|
||||
result=$?
|
||||
set -e
|
||||
|
||||
if [[ "$result" != 0 ]]
|
||||
then
|
||||
echo "Proof $(basename "$new_proof" ".py") failed: $output."
|
||||
error=1
|
||||
if [[ "$result" != 0 ]]
|
||||
then
|
||||
echo "Proof $(basename "$new_proof" ".py") failed: $output."
|
||||
error=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
|
29
test/formal/combine_byte_shl.py
Normal file
29
test/formal/combine_byte_shl.py
Normal file
@ -0,0 +1,29 @@
|
||||
from rule import Rule
|
||||
from opcodes import *
|
||||
|
||||
"""
|
||||
byte(A, shl(B, X))
|
||||
given B % 8 == 0 && A <= 32 && B <= 256
|
||||
->
|
||||
byte(A + B / 8, X)
|
||||
"""
|
||||
|
||||
rule = Rule()
|
||||
|
||||
n_bits = 256
|
||||
|
||||
# Input vars
|
||||
X = BitVec('X', n_bits)
|
||||
A = BitVec('A', n_bits)
|
||||
B = BitVec('B', n_bits)
|
||||
|
||||
# Non optimized result
|
||||
nonopt = BYTE(A, SHL(B, X))
|
||||
# Optimized result
|
||||
opt = BYTE(A + B / 8, X)
|
||||
|
||||
rule.require(B % 8 == 0)
|
||||
rule.require(ULE(A, 32))
|
||||
rule.require(ULE(B, 256))
|
||||
|
||||
rule.check(nonopt, opt)
|
30
test/formal/combine_byte_shr_1.py
Normal file
30
test/formal/combine_byte_shr_1.py
Normal file
@ -0,0 +1,30 @@
|
||||
from rule import Rule
|
||||
from opcodes import *
|
||||
|
||||
"""
|
||||
byte(A, shr(B, X))
|
||||
given B % 8 == 0 && A < n_bits/8 && B <= n_bits && A >= B / 8
|
||||
->
|
||||
byte(A - B / 8, X)
|
||||
"""
|
||||
|
||||
rule = Rule()
|
||||
|
||||
n_bits = 256
|
||||
|
||||
# Input vars
|
||||
X = BitVec('X', n_bits)
|
||||
A = BitVec('A', n_bits)
|
||||
B = BitVec('B', n_bits)
|
||||
|
||||
# Non optimized result
|
||||
nonopt = BYTE(A, SHR(B, X))
|
||||
# Optimized result
|
||||
opt = BYTE(A - B / 8, X)
|
||||
|
||||
rule.require(B % 8 == 0)
|
||||
rule.require(ULT(A, n_bits/8))
|
||||
rule.require(ULE(B, n_bits))
|
||||
rule.require(UGE(A, DIV(B,8)))
|
||||
|
||||
rule.check(nonopt, opt)
|
30
test/formal/combine_byte_shr_2.py
Normal file
30
test/formal/combine_byte_shr_2.py
Normal file
@ -0,0 +1,30 @@
|
||||
from rule import Rule
|
||||
from opcodes import *
|
||||
|
||||
"""
|
||||
byte(A, shr(B, X))
|
||||
given B % 8 == 0 && A < n_bits/8 && B <= n_bits && A < B / 8
|
||||
->
|
||||
0
|
||||
"""
|
||||
|
||||
rule = Rule()
|
||||
|
||||
n_bits = 256
|
||||
|
||||
# Input vars
|
||||
X = BitVec('X', n_bits)
|
||||
A = BitVec('A', n_bits)
|
||||
B = BitVec('B', n_bits)
|
||||
|
||||
# Non optimized result
|
||||
nonopt = BYTE(A, SHR(B, X))
|
||||
# Optimized result
|
||||
opt = 0
|
||||
|
||||
rule.require(B % 8 == 0)
|
||||
rule.require(ULT(A, n_bits/8))
|
||||
rule.require(ULE(B, n_bits))
|
||||
rule.require(ULT(A, DIV(B,8)))
|
||||
|
||||
rule.check(nonopt, opt)
|
@ -56,3 +56,7 @@ def SHR(x, y):
|
||||
|
||||
def SAR(x, y):
|
||||
return y >> x
|
||||
|
||||
def BYTE(i, x):
|
||||
bit = (i + 1) * 8
|
||||
return If(UGT(bit, x.size()), BitVecVal(0, x.size()), (LShR(x, (x.size() - bit))) & 0xff)
|
||||
|
@ -61,18 +61,40 @@ bytes SolidityExecutionFramework::multiSourceCompileContract(
|
||||
evmasm::LinkerObject obj;
|
||||
if (m_compileViaYul)
|
||||
{
|
||||
yul::AssemblyStack asmStack(
|
||||
m_evmVersion,
|
||||
yul::AssemblyStack::Language::StrictAssembly,
|
||||
// Ignore optimiser settings here because we need Yul optimisation to
|
||||
// get code that does not exhaust the stack.
|
||||
OptimiserSettings::full()
|
||||
);
|
||||
bool analysisSuccessful = asmStack.parseAndAnalyze("", m_compiler.yulIROptimized(contractName));
|
||||
solAssert(analysisSuccessful, "Code that passed analysis in CompilerStack can't have errors");
|
||||
// Try compiling twice: If the first run fails due to stack errors, forcefully enable
|
||||
// the optimizer.
|
||||
for (bool forceEnableOptimizer: {false, true})
|
||||
{
|
||||
OptimiserSettings optimiserSettings = m_optimiserSettings;
|
||||
if (!forceEnableOptimizer && !optimiserSettings.runYulOptimiser)
|
||||
{
|
||||
// Enable some optimizations on the first run
|
||||
optimiserSettings.runYulOptimiser = true;
|
||||
optimiserSettings.yulOptimiserSteps = "uljmul jmul";
|
||||
}
|
||||
else if (forceEnableOptimizer)
|
||||
optimiserSettings = OptimiserSettings::full();
|
||||
|
||||
asmStack.optimize();
|
||||
obj = std::move(*asmStack.assemble(yul::AssemblyStack::Machine::EVM).bytecode);
|
||||
yul::AssemblyStack asmStack(
|
||||
m_evmVersion,
|
||||
yul::AssemblyStack::Language::StrictAssembly,
|
||||
optimiserSettings
|
||||
);
|
||||
bool analysisSuccessful = asmStack.parseAndAnalyze("", m_compiler.yulIROptimized(contractName));
|
||||
solAssert(analysisSuccessful, "Code that passed analysis in CompilerStack can't have errors");
|
||||
|
||||
try
|
||||
{
|
||||
asmStack.optimize();
|
||||
obj = std::move(*asmStack.assemble(yul::AssemblyStack::Machine::EVM).bytecode);
|
||||
break;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (forceEnableOptimizer || optimiserSettings == OptimiserSettings::full())
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
obj = m_compiler.object(contractName);
|
||||
|
@ -16,6 +16,7 @@ contract C {
|
||||
return (x[199], y[203][1], z[170].a[1], z[170].b[99]);
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> "A", 8, 4, "B"
|
||||
|
17
test/libsolidity/semanticTests/array/delete_memory_array.sol
Normal file
17
test/libsolidity/semanticTests/array/delete_memory_array.sol
Normal file
@ -0,0 +1,17 @@
|
||||
contract C {
|
||||
|
||||
function len() public returns (uint ret) {
|
||||
uint[] memory data = new uint[](2);
|
||||
data[0] = 234;
|
||||
data[1] = 123;
|
||||
delete data;
|
||||
assembly {
|
||||
ret := mload(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// len() -> 0
|
@ -0,0 +1,40 @@
|
||||
contract C {
|
||||
uint[] data;
|
||||
|
||||
function len() public returns (uint ret) {
|
||||
data.push(234);
|
||||
data.push(123);
|
||||
delete data;
|
||||
assembly {
|
||||
ret := sload(data_slot)
|
||||
}
|
||||
}
|
||||
|
||||
function val() public returns (uint ret) {
|
||||
assembly {
|
||||
sstore(0, 2)
|
||||
mstore(0, 0)
|
||||
sstore(keccak256(0, 32), 234)
|
||||
sstore(add(keccak256(0, 32), 1), 123)
|
||||
}
|
||||
|
||||
assert(data[0] == 234);
|
||||
assert(data[1] == 123);
|
||||
|
||||
delete data;
|
||||
|
||||
uint size = 999;
|
||||
|
||||
assembly {
|
||||
size := sload(0)
|
||||
mstore(0, 0)
|
||||
ret := sload(keccak256(0, 32))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// len() -> 0
|
||||
// val() -> 0
|
@ -0,0 +1,14 @@
|
||||
contract C {
|
||||
function f(uint x) external payable returns (uint) { return 1; }
|
||||
function f(uint x, uint y) external payable returns (uint) { return 2; }
|
||||
function call() public payable returns (uint v, uint x, uint y, uint z) {
|
||||
v = this.f{value: 10}(2);
|
||||
x = this.f{gas: 1000}(2, 3);
|
||||
y = this.f{gas: 1000, value: 10}(2, 3);
|
||||
z = this.f{gas: 1000}{value: 10}(2, 3);
|
||||
}
|
||||
receive() external payable {}
|
||||
}
|
||||
// ----
|
||||
// (), 1 ether
|
||||
// call() -> 1, 2, 2, 2
|
44
test/libsolidity/semanticTests/optimizer/shift_bytes.sol
Normal file
44
test/libsolidity/semanticTests/optimizer/shift_bytes.sol
Normal file
@ -0,0 +1,44 @@
|
||||
// This tests the optimizer rule
|
||||
// byte(A, shl(B, X))
|
||||
// ->
|
||||
// byte(A + B / 8, X)
|
||||
// given A <= 32 && B % 8 == 0 && B <= 256
|
||||
//
|
||||
// and the respective rule about shr
|
||||
contract C {
|
||||
function f(uint a) public returns (uint, uint, uint) {
|
||||
uint x = a << (256 - 8);
|
||||
assembly {
|
||||
x := byte(0, x)
|
||||
}
|
||||
uint y = a << 8;
|
||||
assembly {
|
||||
y := byte(30, y)
|
||||
}
|
||||
uint z = a << 16;
|
||||
assembly {
|
||||
z := byte(1, z)
|
||||
}
|
||||
return (x, y, z);
|
||||
}
|
||||
function g(uint a) public returns (uint, uint, uint) {
|
||||
uint x = a >> (256 - 16);
|
||||
assembly {
|
||||
x := byte(31, x)
|
||||
}
|
||||
uint y = a >> 8;
|
||||
assembly {
|
||||
y := byte(4, y)
|
||||
}
|
||||
uint z = a >> 16;
|
||||
assembly {
|
||||
z := byte(7, z)
|
||||
}
|
||||
return (x, y, z);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(uint256): 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f -> 0x1f, 0x1f, 3
|
||||
// g(uint256): 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f -> 1, 3, 5
|
@ -0,0 +1,19 @@
|
||||
// tests compile-time evaluation of keccak256 on literal strings
|
||||
contract C {
|
||||
function short() public pure returns (bool) {
|
||||
bytes32 a = keccak256("abcdefghijklmn");
|
||||
bytes memory s = "abcdefghijklmn";
|
||||
return a == keccak256(s);
|
||||
}
|
||||
bytes32 constant sc = keccak256("abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn");
|
||||
function long() public pure returns (bool, bool) {
|
||||
bytes32 a = keccak256("abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn");
|
||||
bytes memory s = "abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn";
|
||||
return (a == keccak256(s), sc == keccak256(s));
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// short() -> true
|
||||
// long() -> true, true
|
@ -1,9 +0,0 @@
|
||||
contract C {
|
||||
function f(uint x) external payable { }
|
||||
function f(uint x, uint y) external payable { }
|
||||
function call() internal {
|
||||
this.f{value: 10}(2);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 6675: (148-154): Member "f" not unique after argument-dependent lookup in contract C.
|
@ -29,7 +29,7 @@ using namespace std;
|
||||
namespace solidity::util::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(IpfsHash)
|
||||
BOOST_AUTO_TEST_SUITE(IpfsHash, *boost::unit_test::label("nooptions"))
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_small)
|
||||
{
|
||||
|
@ -29,7 +29,7 @@ using namespace std;
|
||||
namespace solidity::util::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(IterateReplacing)
|
||||
BOOST_AUTO_TEST_SUITE(IterateReplacing, *boost::unit_test::label("nooptions"))
|
||||
|
||||
BOOST_AUTO_TEST_CASE(no_replacement)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ using namespace std;
|
||||
namespace solidity::util::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(JsonTest)
|
||||
BOOST_AUTO_TEST_SUITE(JsonTest, *boost::unit_test::label("nooptions"))
|
||||
|
||||
BOOST_AUTO_TEST_CASE(json_pretty_print)
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ using namespace std;
|
||||
namespace solidity::util::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Keccak256)
|
||||
BOOST_AUTO_TEST_SUITE(Keccak256, *boost::unit_test::label("nooptions"))
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty)
|
||||
{
|
||||
|
@ -59,7 +59,7 @@ T valueOf(LazyInit<T> _lazyInit)
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(LazyInitTests)
|
||||
BOOST_AUTO_TEST_SUITE(LazyInitTests, *boost::unit_test::label("nooptions"))
|
||||
|
||||
BOOST_AUTO_TEST_CASE(default_constructed_is_empty)
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ using namespace std;
|
||||
namespace solidity::util::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(StringUtils)
|
||||
BOOST_AUTO_TEST_SUITE(StringUtils, *boost::unit_test::label("nooptions"))
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_similarity)
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ using namespace std;
|
||||
namespace solidity::util::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(SwarmHash)
|
||||
BOOST_AUTO_TEST_SUITE(SwarmHash, *boost::unit_test::label("nooptions"))
|
||||
|
||||
string bzzr0HashHex(string const& _input)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ using namespace std;
|
||||
namespace solidity::util::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(UTF8)
|
||||
BOOST_AUTO_TEST_SUITE(UTF8, *boost::unit_test::label("nooptions"))
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -29,7 +29,7 @@ using namespace std;
|
||||
namespace solidity::util::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(WhiskersTest)
|
||||
BOOST_AUTO_TEST_SUITE(WhiskersTest, *boost::unit_test::label("nooptions"))
|
||||
|
||||
BOOST_AUTO_TEST_CASE(no_templates)
|
||||
{
|
||||
|
@ -43,7 +43,7 @@ string assemble(string const& _input)
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(StackReuseCodegen)
|
||||
BOOST_AUTO_TEST_SUITE(StackReuseCodegen, *boost::unit_test::label("nooptions"))
|
||||
|
||||
BOOST_AUTO_TEST_CASE(smoke_test)
|
||||
{
|
||||
|
@ -10,7 +10,12 @@ add_dependencies(ossfuzz
|
||||
|
||||
if (OSSFUZZ)
|
||||
add_custom_target(ossfuzz_proto)
|
||||
add_dependencies(ossfuzz_proto yul_proto_ossfuzz yul_proto_diff_ossfuzz sol_proto_ossfuzz)
|
||||
add_dependencies(ossfuzz_proto
|
||||
sol_proto_ossfuzz
|
||||
yul_proto_ossfuzz
|
||||
yul_proto_diff_ossfuzz
|
||||
yul_proto_diff_custom_mutate_ossfuzz
|
||||
)
|
||||
|
||||
add_custom_target(ossfuzz_abiv2)
|
||||
add_dependencies(ossfuzz_abiv2 abiv2_proto_ossfuzz)
|
||||
@ -60,6 +65,22 @@ if (OSSFUZZ)
|
||||
)
|
||||
set_target_properties(yul_proto_diff_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||
|
||||
add_executable(yul_proto_diff_custom_mutate_ossfuzz
|
||||
yulProto_diff_ossfuzz.cpp
|
||||
yulFuzzerCommon.cpp
|
||||
protoToYul.cpp
|
||||
yulProto.pb.cc
|
||||
protomutators/YulProtoMutator.cpp
|
||||
)
|
||||
target_include_directories(yul_proto_diff_custom_mutate_ossfuzz PRIVATE /usr/include/libprotobuf-mutator)
|
||||
target_link_libraries(yul_proto_diff_custom_mutate_ossfuzz PRIVATE yul
|
||||
yulInterpreter
|
||||
protobuf-mutator-libfuzzer.a
|
||||
protobuf-mutator.a
|
||||
protobuf.a
|
||||
)
|
||||
set_target_properties(yul_proto_diff_custom_mutate_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||
|
||||
add_executable(abiv2_proto_ossfuzz
|
||||
../../EVMHost.cpp
|
||||
abiV2ProtoFuzzer.cpp
|
||||
|
@ -178,6 +178,14 @@ bool ProtoConverter::functionCallNotPossible(FunctionCall_Returns _type)
|
||||
(_type == FunctionCall::MULTIASSIGN && !varDeclAvailable());
|
||||
}
|
||||
|
||||
unsigned ProtoConverter::numVarsInScope()
|
||||
{
|
||||
if (m_inFunctionDef)
|
||||
return m_currentFuncVars.size();
|
||||
else
|
||||
return m_currentGlobalVars.size();
|
||||
}
|
||||
|
||||
void ProtoConverter::visit(VarRef const& _x)
|
||||
{
|
||||
if (m_inFunctionDef)
|
||||
@ -827,18 +835,18 @@ void ProtoConverter::visitFunctionInputParams(FunctionCall const& _x, unsigned _
|
||||
case 4:
|
||||
visit(_x.in_param4());
|
||||
m_output << ", ";
|
||||
BOOST_FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
case 3:
|
||||
visit(_x.in_param3());
|
||||
m_output << ", ";
|
||||
BOOST_FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
case 2:
|
||||
visit(_x.in_param2());
|
||||
m_output << ", ";
|
||||
BOOST_FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
case 1:
|
||||
visit(_x.in_param1());
|
||||
BOOST_FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
@ -963,23 +971,43 @@ void ProtoConverter::visit(FunctionCall const& _x)
|
||||
"Proto fuzzer: Function call with too many output params encountered."
|
||||
);
|
||||
|
||||
// Return early if numOutParams > number of available variables
|
||||
if (numOutParams > numVarsInScope())
|
||||
return;
|
||||
|
||||
// Copy variables in scope in order to prevent repeated references
|
||||
vector<string> variables;
|
||||
if (m_inFunctionDef)
|
||||
for (auto var: m_currentFuncVars)
|
||||
variables.push_back(*var);
|
||||
else
|
||||
for (auto var: m_currentGlobalVars)
|
||||
variables.push_back(*var);
|
||||
|
||||
auto refVar = [](vector<string>& _var, unsigned _rand, bool _comma = true) -> string
|
||||
{
|
||||
auto index = _rand % _var.size();
|
||||
string ref = _var[index];
|
||||
_var.erase(_var.begin() + index);
|
||||
if (_comma)
|
||||
ref += ", ";
|
||||
return ref;
|
||||
};
|
||||
|
||||
// Convert LHS of multi assignment
|
||||
// We reverse the order of out param visits since the order does not matter.
|
||||
// This helps reduce the size of this switch statement.
|
||||
switch (numOutParams)
|
||||
{
|
||||
case 4:
|
||||
visit(_x.out_param4());
|
||||
m_output << ", ";
|
||||
BOOST_FALLTHROUGH;
|
||||
m_output << refVar(variables, _x.out_param4().varnum());
|
||||
[[fallthrough]];
|
||||
case 3:
|
||||
visit(_x.out_param3());
|
||||
m_output << ", ";
|
||||
BOOST_FALLTHROUGH;
|
||||
m_output << refVar(variables, _x.out_param3().varnum());
|
||||
[[fallthrough]];
|
||||
case 2:
|
||||
visit(_x.out_param2());
|
||||
m_output << ", ";
|
||||
visit(_x.out_param1());
|
||||
m_output << refVar(variables, _x.out_param2().varnum());
|
||||
m_output << refVar(variables, _x.out_param1().varnum(), false);
|
||||
break;
|
||||
default:
|
||||
yulAssert(false, "Proto fuzzer: Function call with too many or too few input parameters.");
|
||||
|
@ -120,6 +120,8 @@ private:
|
||||
void closeFunctionScope();
|
||||
/// Adds @a _vars to current scope
|
||||
void addVarsToScope(std::vector<std::string> const& _vars);
|
||||
/// @returns number of variables that are in scope
|
||||
unsigned numVarsInScope();
|
||||
|
||||
std::string createHex(std::string const& _hexBytes);
|
||||
|
||||
|
147
test/tools/ossfuzz/protomutators/YulProtoMutator.cpp
Normal file
147
test/tools/ossfuzz/protomutators/YulProtoMutator.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
#include <test/tools/ossfuzz/protomutators/YulProtoMutator.h>
|
||||
|
||||
#include <libyul/Exceptions.h>
|
||||
|
||||
#include <src/text_format.h>
|
||||
|
||||
using namespace solidity::yul::test::yul_fuzzer;
|
||||
using namespace protobuf_mutator;
|
||||
using namespace std;
|
||||
|
||||
using YPM = YulProtoMutator;
|
||||
|
||||
MutationInfo::MutationInfo(ProtobufMessage const* _message, string const& _info):
|
||||
ScopeGuard([&]{ exitInfo(); }),
|
||||
m_protobufMsg(_message)
|
||||
{
|
||||
writeLine("----------------------------------");
|
||||
writeLine("YULMUTATOR: " + _info);
|
||||
writeLine("Before");
|
||||
writeLine(SaveMessageAsText(*m_protobufMsg));
|
||||
}
|
||||
|
||||
void MutationInfo::exitInfo()
|
||||
{
|
||||
writeLine("After");
|
||||
writeLine(SaveMessageAsText(*m_protobufMsg));
|
||||
}
|
||||
|
||||
/// Initialize deterministic PRNG.
|
||||
static YulRandomNumGenerator s_rand(1337);
|
||||
|
||||
/// Add m/sstore(0, variable)
|
||||
static LPMPostProcessor<Block> addStoreToZero(
|
||||
[](Block* _message, unsigned _seed)
|
||||
{
|
||||
if (_seed % YPM::s_highIP == 0)
|
||||
{
|
||||
MutationInfo m{_message, "Added store to zero"};
|
||||
auto storeStmt = new StoreFunc();
|
||||
storeStmt->set_st(YPM::EnumTypeConverter<StoreFunc_Storage>{}.enumFromSeed(s_rand()));
|
||||
storeStmt->set_allocated_loc(YPM::litExpression(0));
|
||||
storeStmt->set_allocated_val(YPM::refExpression(s_rand));
|
||||
auto stmt = _message->add_statements();
|
||||
stmt->set_allocated_storage_func(storeStmt);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Literal* YPM::intLiteral(unsigned _value)
|
||||
{
|
||||
auto lit = new Literal();
|
||||
lit->set_intval(_value);
|
||||
return lit;
|
||||
}
|
||||
|
||||
VarRef* YPM::varRef(unsigned _seed)
|
||||
{
|
||||
auto varref = new VarRef();
|
||||
varref->set_varnum(_seed);
|
||||
return varref;
|
||||
}
|
||||
|
||||
Expression* YPM::refExpression(YulRandomNumGenerator& _rand)
|
||||
{
|
||||
auto refExpr = new Expression();
|
||||
refExpr->set_allocated_varref(varRef(_rand()));
|
||||
return refExpr;
|
||||
}
|
||||
|
||||
Expression* YPM::litExpression(unsigned _value)
|
||||
{
|
||||
auto lit = intLiteral(_value);
|
||||
auto expr = new Expression();
|
||||
expr->set_allocated_cons(lit);
|
||||
return expr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T YPM::EnumTypeConverter<T>::validEnum(unsigned _seed)
|
||||
{
|
||||
auto ret = static_cast<T>(_seed % (enumMax() - enumMin() + 1) + enumMin());
|
||||
if constexpr (std::is_same_v<std::decay_t<T>, FunctionCall_Returns>)
|
||||
yulAssert(FunctionCall_Returns_IsValid(ret), "Yul proto mutator: Invalid enum");
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, StoreFunc_Storage>)
|
||||
yulAssert(StoreFunc_Storage_IsValid(ret), "Yul proto mutator: Invalid enum");
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, NullaryOp_NOp>)
|
||||
yulAssert(NullaryOp_NOp_IsValid(ret), "Yul proto mutator: Invalid enum");
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, BinaryOp_BOp>)
|
||||
yulAssert(BinaryOp_BOp_IsValid(ret), "Yul proto mutator: Invalid enum");
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, UnaryOp_UOp>)
|
||||
yulAssert(UnaryOp_UOp_IsValid(ret), "Yul proto mutator: Invalid enum");
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, LowLevelCall_Type>)
|
||||
yulAssert(LowLevelCall_Type_IsValid(ret), "Yul proto mutator: Invalid enum");
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, Create_Type>)
|
||||
yulAssert(Create_Type_IsValid(ret), "Yul proto mutator: Invalid enum");
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, UnaryOpData_UOpData>)
|
||||
yulAssert(UnaryOpData_UOpData_IsValid(ret), "Yul proto mutator: Invalid enum");
|
||||
else
|
||||
static_assert(AlwaysFalse<T>::value, "Yul proto mutator: non-exhaustive visitor.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned YPM::EnumTypeConverter<T>::enumMax()
|
||||
{
|
||||
if constexpr (std::is_same_v<std::decay_t<T>, FunctionCall_Returns>)
|
||||
return FunctionCall_Returns_Returns_MAX;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, StoreFunc_Storage>)
|
||||
return StoreFunc_Storage_Storage_MAX;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, NullaryOp_NOp>)
|
||||
return NullaryOp_NOp_NOp_MAX;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, BinaryOp_BOp>)
|
||||
return BinaryOp_BOp_BOp_MAX;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, UnaryOp_UOp>)
|
||||
return UnaryOp_UOp_UOp_MAX;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, LowLevelCall_Type>)
|
||||
return LowLevelCall_Type_Type_MAX;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, Create_Type>)
|
||||
return Create_Type_Type_MAX;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, UnaryOpData_UOpData>)
|
||||
return UnaryOpData_UOpData_UOpData_MAX;
|
||||
else
|
||||
static_assert(AlwaysFalse<T>::value, "Yul proto mutator: non-exhaustive visitor.");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned YPM::EnumTypeConverter<T>::enumMin()
|
||||
{
|
||||
if constexpr (std::is_same_v<std::decay_t<T>, FunctionCall_Returns>)
|
||||
return FunctionCall_Returns_Returns_MIN;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, StoreFunc_Storage>)
|
||||
return StoreFunc_Storage_Storage_MIN;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, NullaryOp_NOp>)
|
||||
return NullaryOp_NOp_NOp_MIN;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, BinaryOp_BOp>)
|
||||
return BinaryOp_BOp_BOp_MIN;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, UnaryOp_UOp>)
|
||||
return UnaryOp_UOp_UOp_MIN;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, LowLevelCall_Type>)
|
||||
return LowLevelCall_Type_Type_MIN;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, Create_Type>)
|
||||
return Create_Type_Type_MIN;
|
||||
else if constexpr (std::is_same_v<std::decay_t<T>, UnaryOpData_UOpData>)
|
||||
return UnaryOpData_UOpData_UOpData_MIN;
|
||||
else
|
||||
static_assert(AlwaysFalse<T>::value, "Yul proto mutator: non-exhaustive visitor.");
|
||||
}
|
98
test/tools/ossfuzz/protomutators/YulProtoMutator.h
Normal file
98
test/tools/ossfuzz/protomutators/YulProtoMutator.h
Normal file
@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
|
||||
#include <test/tools/ossfuzz/yulProto.pb.h>
|
||||
|
||||
#include <libsolutil/Common.h>
|
||||
|
||||
#include <src/libfuzzer/libfuzzer_macro.h>
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace solidity::yul::test::yul_fuzzer
|
||||
{
|
||||
|
||||
using ProtobufMessage = google::protobuf::Message;
|
||||
|
||||
template <typename Proto>
|
||||
using LPMPostProcessor = protobuf_mutator::libfuzzer::PostProcessorRegistration<Proto>;
|
||||
|
||||
class MutationInfo: public ScopeGuard
|
||||
{
|
||||
public:
|
||||
MutationInfo(ProtobufMessage const* _message, std::string const& _info);
|
||||
|
||||
static void writeLine(std::string const& _str)
|
||||
{
|
||||
std::cout << _str << std::endl;
|
||||
}
|
||||
void exitInfo();
|
||||
|
||||
ProtobufMessage const* m_protobufMsg;
|
||||
};
|
||||
|
||||
struct YulRandomNumGenerator
|
||||
{
|
||||
using RandomEngine = std::minstd_rand;
|
||||
|
||||
explicit YulRandomNumGenerator(unsigned _seed): m_random(RandomEngine(_seed)) {}
|
||||
|
||||
unsigned operator()()
|
||||
{
|
||||
return m_random();
|
||||
}
|
||||
|
||||
RandomEngine m_random;
|
||||
};
|
||||
|
||||
struct YulProtoMutator
|
||||
{
|
||||
/// @param _value: Value of the integer literal
|
||||
/// @returns an integer literal protobuf message initialized with
|
||||
/// the given value.
|
||||
static Literal* intLiteral(unsigned _value);
|
||||
|
||||
/// @param _seed: Pseudo-random unsigned integer used as index
|
||||
/// of variable to be referenced
|
||||
/// @returns a variable reference protobuf message.
|
||||
static VarRef* varRef(unsigned _seed);
|
||||
|
||||
/// @param _value: value of literal expression
|
||||
/// @returns an expression protobuf message
|
||||
static Expression* litExpression(unsigned _value);
|
||||
|
||||
/// @param _rand: Pseudo-random number generator
|
||||
/// of variable to be referenced
|
||||
/// @returns a variable reference protobuf message
|
||||
static Expression* refExpression(YulRandomNumGenerator& _rand);
|
||||
|
||||
/// Helper type for type matching visitor.
|
||||
template<class T> struct AlwaysFalse: std::false_type {};
|
||||
|
||||
/// Template struct for obtaining a valid enum value of
|
||||
/// template type from a pseudo-random unsigned integer.
|
||||
/// @param _seed: Pseudo-random integer
|
||||
/// @returns Valid enum of enum type T
|
||||
template <typename T>
|
||||
struct EnumTypeConverter
|
||||
{
|
||||
T enumFromSeed(unsigned _seed)
|
||||
{
|
||||
return validEnum(_seed);
|
||||
}
|
||||
|
||||
/// @returns a valid enum of type T from _seed
|
||||
T validEnum(unsigned _seed);
|
||||
/// @returns maximum enum value for enum of type T
|
||||
static unsigned enumMax();
|
||||
/// @returns minimum enum value for enum of type T
|
||||
static unsigned enumMin();
|
||||
};
|
||||
|
||||
/// Modulo for mutations that should occur rarely
|
||||
static constexpr unsigned s_lowIP = 31;
|
||||
/// Modulo for mutations that should occur not too often
|
||||
static constexpr unsigned s_mediumIP = 29;
|
||||
/// Modulo for mutations that should occur often
|
||||
static constexpr unsigned s_highIP = 23;
|
||||
};
|
||||
}
|
@ -121,7 +121,7 @@ protected:
|
||||
RandomisingAlgorithm m_algorithm;
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(AlgorithmRunnerTest)
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(run_should_call_runNextRound_once_per_round, AlgorithmRunnerFixture)
|
||||
|
@ -46,7 +46,7 @@ using namespace solidity::util;
|
||||
namespace solidity::phaser::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(ChromosomeTest)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(constructor_should_convert_from_string_to_optimisation_steps)
|
||||
|
@ -66,7 +66,7 @@ map<string, TestEnum> const StringToTestEnumMap = invertMap(TestEnumToStringMap)
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(CommonTest)
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(readLinesFromFile_should_return_all_lines_from_a_text_file_as_strings_without_newlines, ReadLinesFromFileFixture)
|
||||
|
@ -95,7 +95,7 @@ protected:
|
||||
};
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(FitnessMetricsTest)
|
||||
BOOST_AUTO_TEST_SUITE(ProgramBasedMetricTest)
|
||||
|
||||
|
@ -56,7 +56,7 @@ protected:
|
||||
};
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(GeneticAlgorithmsTest)
|
||||
BOOST_AUTO_TEST_SUITE(RandomAlgorithmTest)
|
||||
|
||||
@ -212,7 +212,8 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_generate_individuals_in_the_crossove
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
BOOST_AUTO_TEST_SUITE(ClassicGeneticAlgorithmTest)
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(runNextRound_should_select_individuals_with_probability_proportional_to_fitness, ClassicGeneticAlgorithmFixture)
|
||||
// FIXME: This test runs *very* slowly (tens of seconds). Investigate, fix and re-enable.
|
||||
BOOST_FIXTURE_TEST_CASE(runNextRound_should_select_individuals_with_probability_proportional_to_fitness, ClassicGeneticAlgorithmFixture, *boost::unit_test::disabled())
|
||||
{
|
||||
constexpr double relativeTolerance = 0.1;
|
||||
constexpr size_t populationSize = 1000;
|
||||
@ -253,7 +254,8 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_select_individuals_with_probability_
|
||||
BOOST_TEST(abs(meanSquaredError(newFitness, expectedValue) - variance) < variance * relativeTolerance);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(runNextRound_should_select_only_individuals_existing_in_the_original_population, ClassicGeneticAlgorithmFixture)
|
||||
// FIXME: This test runs *very* slowly (tens of seconds). Investigate, fix and re-enable.
|
||||
BOOST_FIXTURE_TEST_CASE(runNextRound_should_select_only_individuals_existing_in_the_original_population, ClassicGeneticAlgorithmFixture, *boost::unit_test::disabled())
|
||||
{
|
||||
constexpr size_t populationSize = 1000;
|
||||
auto population = Population::makeRandom(m_fitnessMetric, populationSize, 1, 10);
|
||||
@ -297,7 +299,8 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_crossover, ClassicGeneticAlgorith
|
||||
BOOST_TEST(totalCrossed >= 2);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_mutation, ClassicGeneticAlgorithmFixture)
|
||||
// FIXME: This test runs *very* slowly (tens of seconds). Investigate, fix and re-enable.
|
||||
BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_mutation, ClassicGeneticAlgorithmFixture, *boost::unit_test::disabled())
|
||||
{
|
||||
m_options.mutationChance = 0.6;
|
||||
ClassicGeneticAlgorithm algorithm(m_options);
|
||||
@ -326,7 +329,8 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_mutation, ClassicGeneticAlgorithm
|
||||
BOOST_TEST(abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_deletion, ClassicGeneticAlgorithmFixture)
|
||||
// FIXME: This test runs *very* slowly (tens of seconds). Investigate, fix and re-enable.
|
||||
BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_deletion, ClassicGeneticAlgorithmFixture, *boost::unit_test::disabled())
|
||||
{
|
||||
m_options.deletionChance = 0.6;
|
||||
ClassicGeneticAlgorithm algorithm(m_options);
|
||||
@ -355,7 +359,8 @@ BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_deletion, ClassicGeneticAlgorithm
|
||||
BOOST_TEST(abs(meanSquaredError(bernoulliTrials, expectedValue) - variance) < variance * relativeTolerance);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_addition, ClassicGeneticAlgorithmFixture)
|
||||
// FIXME: This test runs *very* slowly (tens of seconds). Investigate, fix and re-enable.
|
||||
BOOST_FIXTURE_TEST_CASE(runNextRound_should_do_addition, ClassicGeneticAlgorithmFixture, *boost::unit_test::disabled())
|
||||
{
|
||||
m_options.additionChance = 0.6;
|
||||
ClassicGeneticAlgorithm algorithm(m_options);
|
||||
|
@ -33,7 +33,7 @@ using namespace solidity::util;
|
||||
namespace solidity::phaser::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(MutationsTest)
|
||||
BOOST_AUTO_TEST_SUITE(GeneRandomisationTest)
|
||||
|
||||
|
@ -31,7 +31,7 @@ using namespace std;
|
||||
namespace solidity::phaser::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(PairSelectionsTest)
|
||||
BOOST_AUTO_TEST_SUITE(RandomPairSelectionTest)
|
||||
|
||||
|
@ -103,7 +103,7 @@ protected:
|
||||
};
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(PhaserTest)
|
||||
BOOST_AUTO_TEST_SUITE(GeneticAlgorithmFactoryTest)
|
||||
|
||||
|
@ -59,7 +59,7 @@ protected:
|
||||
shared_ptr<FitnessMetric> m_fitnessMetric = make_shared<ChromosomeLengthMetric>();
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(PopulationTest)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(isFitter_should_use_fitness_as_the_main_criterion)
|
||||
|
@ -57,7 +57,7 @@ namespace
|
||||
namespace solidity::phaser::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(ProgramTest)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(copy_constructor_should_make_deep_copy_of_ast)
|
||||
|
@ -70,7 +70,7 @@ protected:
|
||||
ProgramCache m_programCache{m_program};
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(ProgramCacheTest)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(CacheStats_operator_plus_should_add_stats_together)
|
||||
|
@ -34,7 +34,7 @@ using namespace solidity::util;
|
||||
namespace solidity::phaser::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(SelectionsTest)
|
||||
BOOST_AUTO_TEST_SUITE(RangeSelectionTest)
|
||||
|
||||
|
@ -28,7 +28,7 @@ using namespace std;
|
||||
namespace solidity::phaser::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(RandomTest)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(bernoulliTrial_should_produce_samples_with_right_expected_value_and_variance)
|
||||
|
@ -34,7 +34,7 @@ namespace fs = boost::filesystem;
|
||||
namespace solidity::phaser::test
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Phaser)
|
||||
BOOST_AUTO_TEST_SUITE(Phaser, *boost::unit_test::label("nooptions"))
|
||||
BOOST_AUTO_TEST_SUITE(TestHelpersTest)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ChromosomeLengthMetric_evaluate_should_return_chromosome_length)
|
||||
|
Loading…
Reference in New Issue
Block a user