aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/types.rst3
-rw-r--r--libdevcore/Common.h8
-rw-r--r--libdevcore/CommonData.cpp2
-rw-r--r--libdevcore/CommonData.h6
-rw-r--r--libdevcore/FixedHash.h16
-rw-r--r--libevmasm/Assembly.cpp26
-rw-r--r--libevmasm/AssemblyItem.h2
-rw-r--r--libevmasm/Instruction.h8
-rw-r--r--libevmasm/SimplificationRules.cpp6
-rw-r--r--liblll/CodeFragment.cpp2
-rw-r--r--libsolidity/analysis/ReferencesResolver.cpp8
-rw-r--r--libsolidity/ast/ASTJsonConverter.cpp2
-rw-r--r--libsolidity/ast/Types.cpp4
-rw-r--r--libsolidity/ast/Types.h9
-rw-r--r--libsolidity/codegen/CompilerContext.cpp5
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp18
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.cpp22
-rw-r--r--libsolidity/inlineasm/AsmData.h19
-rw-r--r--libsolidity/inlineasm/AsmParser.cpp20
-rw-r--r--libsolidity/inlineasm/AsmPrinter.cpp22
-rw-r--r--libsolidity/inlineasm/AsmPrinter.h4
-rw-r--r--libsolidity/inlineasm/AsmScope.cpp10
-rw-r--r--libsolidity/inlineasm/AsmScope.h18
-rw-r--r--libsolidity/inlineasm/AsmScopeFiller.cpp10
-rw-r--r--libsolidity/interface/Version.cpp6
-rw-r--r--libyul/ASTDataForward.h1
-rw-r--r--libyul/YulString.h96
-rw-r--r--libyul/backends/evm/EVMAssembly.cpp14
-rw-r--r--libyul/backends/evm/EVMCodeTransform.cpp12
-rw-r--r--libyul/backends/evm/EVMCodeTransform.h2
-rw-r--r--libyul/optimiser/ASTCopier.cpp4
-rw-r--r--libyul/optimiser/ASTCopier.h4
-rw-r--r--libyul/optimiser/ASTWalker.h1
-rw-r--r--libyul/optimiser/CommonSubexpressionEliminator.cpp4
-rw-r--r--libyul/optimiser/DataFlowAnalyzer.cpp26
-rw-r--r--libyul/optimiser/DataFlowAnalyzer.h17
-rw-r--r--libyul/optimiser/Disambiguator.cpp2
-rw-r--r--libyul/optimiser/Disambiguator.h8
-rw-r--r--libyul/optimiser/ExpressionInliner.cpp2
-rw-r--r--libyul/optimiser/ExpressionInliner.h6
-rw-r--r--libyul/optimiser/ExpressionJoiner.h6
-rw-r--r--libyul/optimiser/ExpressionSimplifier.h4
-rw-r--r--libyul/optimiser/ExpressionSplitter.cpp4
-rw-r--r--libyul/optimiser/FullInliner.cpp18
-rw-r--r--libyul/optimiser/FullInliner.h28
-rw-r--r--libyul/optimiser/InlinableExpressionFunctionFinder.cpp4
-rw-r--r--libyul/optimiser/InlinableExpressionFunctionFinder.h8
-rw-r--r--libyul/optimiser/MainFunction.cpp4
-rw-r--r--libyul/optimiser/NameCollector.cpp14
-rw-r--r--libyul/optimiser/NameCollector.h17
-rw-r--r--libyul/optimiser/NameDispenser.cpp16
-rw-r--r--libyul/optimiser/NameDispenser.h11
-rw-r--r--libyul/optimiser/RedundantAssignEliminator.cpp6
-rw-r--r--libyul/optimiser/RedundantAssignEliminator.h15
-rw-r--r--libyul/optimiser/Rematerialiser.cpp2
-rw-r--r--libyul/optimiser/Rematerialiser.h4
-rw-r--r--libyul/optimiser/SSATransform.cpp8
-rw-r--r--libyul/optimiser/SSATransform.h6
-rw-r--r--libyul/optimiser/SSAValueTracker.cpp2
-rw-r--r--libyul/optimiser/SSAValueTracker.h9
-rw-r--r--libyul/optimiser/Semantics.cpp2
-rw-r--r--libyul/optimiser/Semantics.h6
-rw-r--r--libyul/optimiser/SimplificationRules.cpp20
-rw-r--r--libyul/optimiser/SimplificationRules.h4
-rw-r--r--libyul/optimiser/Substitution.cpp2
-rw-r--r--libyul/optimiser/Substitution.h8
-rw-r--r--libyul/optimiser/Suite.cpp4
-rw-r--r--libyul/optimiser/Suite.h6
-rw-r--r--libyul/optimiser/SyntacticalEquality.cpp1
-rw-r--r--libyul/optimiser/UnusedPruner.cpp8
-rw-r--r--libyul/optimiser/UnusedPruner.h12
-rw-r--r--libyul/optimiser/VarDeclPropagator.cpp4
-rw-r--r--libyul/optimiser/VarDeclPropagator.h4
-rw-r--r--test/ExecutionFramework.h4
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp76
-rw-r--r--test/libsolidity/SolidityExpressionCompiler.cpp228
-rw-r--r--test/libsolidity/syntaxTests/conversion/function_type_nonpayable_payable.sol10
-rw-r--r--test/libsolidity/syntaxTests/conversion/function_type_nonpayable_pure.sol10
-rw-r--r--test/libsolidity/syntaxTests/conversion/function_type_nonpayable_view.sol10
-rw-r--r--test/libsolidity/syntaxTests/conversion/function_type_payable_nonpayable.sol8
-rw-r--r--test/libsolidity/syntaxTests/conversion/function_type_payable_pure.sol10
-rw-r--r--test/libsolidity/syntaxTests/conversion/function_type_payable_view.sol10
-rw-r--r--test/libsolidity/syntaxTests/conversion/function_type_pure_nonpayable.sol8
-rw-r--r--test/libsolidity/syntaxTests/conversion/function_type_pure_payable.sol10
-rw-r--r--test/libsolidity/syntaxTests/conversion/function_type_pure_view.sol8
-rw-r--r--test/libsolidity/syntaxTests/conversion/function_type_same.sol14
-rw-r--r--test/libsolidity/syntaxTests/conversion/function_type_view_nonpayable.sol10
-rw-r--r--test/libsolidity/syntaxTests/conversion/function_type_view_payable.sol10
-rw-r--r--test/libsolidity/syntaxTests/conversion/function_type_view_pure.sol10
-rw-r--r--test/libsolidity/syntaxTests/types/rational_negative_numerator_negative_exp.sol5
-rw-r--r--test/libyul/Inliner.cpp8
-rw-r--r--test/tools/yulopti.cpp6
92 files changed, 721 insertions, 456 deletions
diff --git a/docs/types.rst b/docs/types.rst
index bd5d1734..34b94b88 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -1225,7 +1225,6 @@ is possible if it
makes sense semantically and no information is lost: ``uint8`` is convertible to
``uint16`` and ``int128`` to ``int256``, but ``int8`` is not convertible to ``uint256``
(because ``uint256`` cannot hold e.g. ``-1``).
-Any integer type that can be converted to ``uint160`` can also be converted to ``address``.
For more details, please consult the sections about the types themselves.
@@ -1335,4 +1334,4 @@ Addresses
As described in :ref:`address_literals`, hex literals of the correct size that pass the checksum
test are of ``address`` type. No other literals can be implicitly converted to the ``address`` type.
-Explicit conversions from ``bytes20`` or any integer type to ``address`` results in ``address payable``. \ No newline at end of file
+Explicit conversions from ``bytes20`` or any integer type to ``address`` result in ``address payable``.
diff --git a/libdevcore/Common.h b/libdevcore/Common.h
index 0363d9a2..6208424e 100644
--- a/libdevcore/Common.h
+++ b/libdevcore/Common.h
@@ -64,15 +64,13 @@
#include <functional>
#include <string>
-using byte = uint8_t;
-
namespace dev
{
// Binary data types.
-using bytes = std::vector<byte>;
-using bytesRef = vector_ref<byte>;
-using bytesConstRef = vector_ref<byte const>;
+using bytes = std::vector<uint8_t>;
+using bytesRef = vector_ref<uint8_t>;
+using bytesConstRef = vector_ref<uint8_t const>;
// Numeric types.
using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;
diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp
index fa1a5353..91c60ffe 100644
--- a/libdevcore/CommonData.cpp
+++ b/libdevcore/CommonData.cpp
@@ -64,7 +64,7 @@ bytes dev::fromHex(std::string const& _s, WhenError _throw)
int h = fromHex(_s[i], WhenError::DontThrow);
int l = fromHex(_s[i + 1], WhenError::DontThrow);
if (h != -1 && l != -1)
- ret.push_back((byte)(h * 16 + l));
+ ret.push_back((uint8_t)(h * 16 + l));
else if (_throw == WhenError::Throw)
BOOST_THROW_EXCEPTION(BadHexCharacter());
else
diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h
index 0782fabc..fedd3af2 100644
--- a/libdevcore/CommonData.h
+++ b/libdevcore/CommonData.h
@@ -88,7 +88,7 @@ inline std::string asString(bytesConstRef _b)
/// Converts a string to a byte array containing the string's (byte) data.
inline bytes asBytes(std::string const& _b)
{
- return bytes((byte const*)_b.data(), (byte const*)(_b.data() + _b.size()));
+ return bytes((uint8_t const*)_b.data(), (uint8_t const*)(_b.data() + _b.size()));
}
// Big-endian to/from host endian conversion functions.
@@ -117,7 +117,7 @@ inline T fromBigEndian(_In const& _bytes)
{
T ret = (T)0;
for (auto i: _bytes)
- ret = (T)((ret << 8) | (byte)(typename std::make_unsigned<typename _In::value_type>::type)i);
+ ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename _In::value_type>::type)i);
return ret;
}
inline bytes toBigEndian(u256 _val) { bytes ret(32); toBigEndian(_val, ret); return ret; }
@@ -135,7 +135,7 @@ inline bytes toCompactBigEndian(T _val, unsigned _min = 0)
toBigEndian(_val, ret);
return ret;
}
-inline bytes toCompactBigEndian(byte _val, unsigned _min = 0)
+inline bytes toCompactBigEndian(uint8_t _val, unsigned _min = 0)
{
return (_min || _val) ? bytes{ _val } : bytes{};
}
diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h
index cd6e1da1..24b89840 100644
--- a/libdevcore/FixedHash.h
+++ b/libdevcore/FixedHash.h
@@ -79,7 +79,7 @@ public:
operator Arith() const { return fromBigEndian<Arith>(m_data); }
/// @returns true iff this is the empty hash.
- explicit operator bool() const { return std::any_of(m_data.begin(), m_data.end(), [](byte _b) { return _b != 0; }); }
+ explicit operator bool() const { return std::any_of(m_data.begin(), m_data.end(), [](uint8_t _b) { return _b != 0; }); }
// The obvious comparison operators.
bool operator==(FixedHash const& _c) const { return m_data == _c.m_data; }
@@ -90,9 +90,9 @@ public:
FixedHash operator~() const { FixedHash ret; for (unsigned i = 0; i < N; ++i) ret[i] = ~m_data[i]; return ret; }
/// @returns a particular byte from the hash.
- byte& operator[](unsigned _i) { return m_data[_i]; }
+ uint8_t& operator[](unsigned _i) { return m_data[_i]; }
/// @returns a particular byte from the hash.
- byte operator[](unsigned _i) const { return m_data[_i]; }
+ uint8_t operator[](unsigned _i) const { return m_data[_i]; }
/// @returns the hash as a user-readable hex string.
std::string hex() const { return toHex(ref()); }
@@ -104,19 +104,19 @@ public:
bytesConstRef ref() const { return bytesConstRef(m_data.data(), N); }
/// @returns a mutable byte pointer to the object's data.
- byte* data() { return m_data.data(); }
+ uint8_t* data() { return m_data.data(); }
/// @returns a constant byte pointer to the object's data.
- byte const* data() const { return m_data.data(); }
+ uint8_t const* data() const { return m_data.data(); }
/// @returns a copy of the object's data as a byte vector.
bytes asBytes() const { return bytes(data(), data() + N); }
/// @returns a mutable reference to the object's data as an STL array.
- std::array<byte, N>& asArray() { return m_data; }
+ std::array<uint8_t, N>& asArray() { return m_data; }
/// @returns a constant reference to the object's data as an STL array.
- std::array<byte, N> const& asArray() const { return m_data; }
+ std::array<uint8_t, N> const& asArray() const { return m_data; }
/// Returns the index of the first bit set to one, or size() * 8 if no bits are set.
inline unsigned firstBitSet() const
@@ -137,7 +137,7 @@ public:
void clear() { m_data.fill(0); }
private:
- std::array<byte, N> m_data; ///< The binary data.
+ std::array<uint8_t, N> m_data; ///< The binary data.
};
/// Stream I/O for the FixedHash class.
diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp
index c2eaa1ca..e63194a0 100644
--- a/libevmasm/Assembly.cpp
+++ b/libevmasm/Assembly.cpp
@@ -525,14 +525,14 @@ LinkerObject const& Assembly::assemble() const
multimap<size_t, size_t> subRef;
vector<unsigned> sizeRef; ///< Pointers to code locations where the size of the program is inserted
unsigned bytesPerTag = dev::bytesRequired(bytesRequiredForCode);
- byte tagPush = (byte)Instruction::PUSH1 - 1 + bytesPerTag;
+ uint8_t tagPush = (uint8_t)Instruction::PUSH1 - 1 + bytesPerTag;
unsigned bytesRequiredIncludingData = bytesRequiredForCode + 1 + m_auxiliaryData.size();
for (auto const& sub: m_subs)
bytesRequiredIncludingData += sub->assemble().bytecode.size();
unsigned bytesPerDataRef = dev::bytesRequired(bytesRequiredIncludingData);
- byte dataRefPush = (byte)Instruction::PUSH1 - 1 + bytesPerDataRef;
+ uint8_t dataRefPush = (uint8_t)Instruction::PUSH1 - 1 + bytesPerDataRef;
ret.bytecode.reserve(bytesRequiredIncludingData);
for (AssemblyItem const& i: m_items)
@@ -544,25 +544,25 @@ LinkerObject const& Assembly::assemble() const
switch (i.type())
{
case Operation:
- ret.bytecode.push_back((byte)i.instruction());
+ ret.bytecode.push_back((uint8_t)i.instruction());
break;
case PushString:
{
- ret.bytecode.push_back((byte)Instruction::PUSH32);
+ ret.bytecode.push_back((uint8_t)Instruction::PUSH32);
unsigned ii = 0;
for (auto j: m_strings.at((h256)i.data()))
if (++ii > 32)
break;
else
- ret.bytecode.push_back((byte)j);
+ ret.bytecode.push_back((uint8_t)j);
while (ii++ < 32)
ret.bytecode.push_back(0);
break;
}
case Push:
{
- byte b = max<unsigned>(1, dev::bytesRequired(i.data()));
- ret.bytecode.push_back((byte)Instruction::PUSH1 - 1 + b);
+ uint8_t b = max<unsigned>(1, dev::bytesRequired(i.data()));
+ ret.bytecode.push_back((uint8_t)Instruction::PUSH1 - 1 + b);
ret.bytecode.resize(ret.bytecode.size() + b);
bytesRef byr(&ret.bytecode.back() + 1 - b, b);
toBigEndian(i.data(), byr);
@@ -589,8 +589,8 @@ LinkerObject const& Assembly::assemble() const
{
auto s = m_subs.at(size_t(i.data()))->assemble().bytecode.size();
i.setPushedValue(u256(s));
- byte b = max<unsigned>(1, dev::bytesRequired(s));
- ret.bytecode.push_back((byte)Instruction::PUSH1 - 1 + b);
+ uint8_t b = max<unsigned>(1, dev::bytesRequired(s));
+ ret.bytecode.push_back((uint8_t)Instruction::PUSH1 - 1 + b);
ret.bytecode.resize(ret.bytecode.size() + b);
bytesRef byr(&ret.bytecode.back() + 1 - b, b);
toBigEndian(s, byr);
@@ -604,12 +604,12 @@ LinkerObject const& Assembly::assemble() const
break;
}
case PushLibraryAddress:
- ret.bytecode.push_back(byte(Instruction::PUSH20));
+ ret.bytecode.push_back(uint8_t(Instruction::PUSH20));
ret.linkReferences[ret.bytecode.size()] = m_libraries.at(i.data());
ret.bytecode.resize(ret.bytecode.size() + 20);
break;
case PushDeployTimeAddress:
- ret.bytecode.push_back(byte(Instruction::PUSH20));
+ ret.bytecode.push_back(uint8_t(Instruction::PUSH20));
ret.bytecode.resize(ret.bytecode.size() + 20);
break;
case Tag:
@@ -618,7 +618,7 @@ LinkerObject const& Assembly::assemble() const
assertThrow(ret.bytecode.size() < 0xffffffffL, AssemblyException, "Tag too large.");
assertThrow(m_tagPositionsInBytecode[size_t(i.data())] == size_t(-1), AssemblyException, "Duplicate tag position.");
m_tagPositionsInBytecode[size_t(i.data())] = ret.bytecode.size();
- ret.bytecode.push_back((byte)Instruction::JUMPDEST);
+ ret.bytecode.push_back((uint8_t)Instruction::JUMPDEST);
break;
default:
BOOST_THROW_EXCEPTION(InvalidOpcode());
@@ -627,7 +627,7 @@ LinkerObject const& Assembly::assemble() const
if (!m_subs.empty() || !m_data.empty() || !m_auxiliaryData.empty())
// Append an INVALID here to help tests find miscompilation.
- ret.bytecode.push_back(byte(Instruction::INVALID));
+ ret.bytecode.push_back(uint8_t(Instruction::INVALID));
for (size_t i = 0; i < m_subs.size(); ++i)
{
diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h
index 5319a2b6..6187e18f 100644
--- a/libevmasm/AssemblyItem.h
+++ b/libevmasm/AssemblyItem.h
@@ -69,7 +69,7 @@ public:
m_location(_location)
{
if (m_type == Operation)
- m_instruction = Instruction(byte(_data));
+ m_instruction = Instruction(uint8_t(_data));
else
m_data = std::make_shared<u256>(_data);
}
diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h
index 63424eeb..539a83b0 100644
--- a/libevmasm/Instruction.h
+++ b/libevmasm/Instruction.h
@@ -228,25 +228,25 @@ inline bool isLogInstruction(Instruction _inst)
/// @returns the number of PUSH Instruction _inst
inline unsigned getPushNumber(Instruction _inst)
{
- return (byte)_inst - unsigned(Instruction::PUSH1) + 1;
+ return (uint8_t)_inst - unsigned(Instruction::PUSH1) + 1;
}
/// @returns the number of DUP Instruction _inst
inline unsigned getDupNumber(Instruction _inst)
{
- return (byte)_inst - unsigned(Instruction::DUP1) + 1;
+ return (uint8_t)_inst - unsigned(Instruction::DUP1) + 1;
}
/// @returns the number of SWAP Instruction _inst
inline unsigned getSwapNumber(Instruction _inst)
{
- return (byte)_inst - unsigned(Instruction::SWAP1) + 1;
+ return (uint8_t)_inst - unsigned(Instruction::SWAP1) + 1;
}
/// @returns the number of LOG Instruction _inst
inline unsigned getLogNumber(Instruction _inst)
{
- return (byte)_inst - unsigned(Instruction::LOG0);
+ return (uint8_t)_inst - unsigned(Instruction::LOG0);
}
/// @returns the PUSH<_number> instruction
diff --git a/libevmasm/SimplificationRules.cpp b/libevmasm/SimplificationRules.cpp
index ba13a611..120d1787 100644
--- a/libevmasm/SimplificationRules.cpp
+++ b/libevmasm/SimplificationRules.cpp
@@ -48,7 +48,7 @@ SimplificationRule<Pattern> const* Rules::findFirstMatch(
resetMatchGroups();
assertThrow(_expr.item, OptimizerException, "");
- for (auto const& rule: m_rules[byte(_expr.item->instruction())])
+ for (auto const& rule: m_rules[uint8_t(_expr.item->instruction())])
{
if (rule.pattern.matches(_expr, _classes))
return &rule;
@@ -59,7 +59,7 @@ SimplificationRule<Pattern> const* Rules::findFirstMatch(
bool Rules::isInitialized() const
{
- return !m_rules[byte(Instruction::ADD)].empty();
+ return !m_rules[uint8_t(Instruction::ADD)].empty();
}
void Rules::addRules(std::vector<SimplificationRule<Pattern>> const& _rules)
@@ -70,7 +70,7 @@ void Rules::addRules(std::vector<SimplificationRule<Pattern>> const& _rules)
void Rules::addRule(SimplificationRule<Pattern> const& _rule)
{
- m_rules[byte(_rule.pattern.instruction())].push_back(_rule);
+ m_rules[uint8_t(_rule.pattern.instruction())].push_back(_rule);
}
Rules::Rules()
diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp
index 0aef05a9..85480119 100644
--- a/liblll/CodeFragment.cpp
+++ b/liblll/CodeFragment.cpp
@@ -348,7 +348,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
else if (i.which() == sp::utree_type::string_type)
{
auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
- data.insert(data.end(), (byte const *)sr.begin(), (byte const*)sr.end());
+ data.insert(data.end(), (uint8_t const *)sr.begin(), (uint8_t const*)sr.end());
}
else if (i.which() == sp::utree_type::any_type)
{
diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp
index f62d9c3b..2adc8e77 100644
--- a/libsolidity/analysis/ReferencesResolver.cpp
+++ b/libsolidity/analysis/ReferencesResolver.cpp
@@ -271,16 +271,16 @@ bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly)
ErrorReporter errorsIgnored(errors);
yul::ExternalIdentifierAccess::Resolver resolver =
[&](assembly::Identifier const& _identifier, yul::IdentifierContext, bool _crossesFunctionBoundary) {
- auto declarations = m_resolver.nameFromCurrentScope(_identifier.name);
- bool isSlot = boost::algorithm::ends_with(_identifier.name, "_slot");
- bool isOffset = boost::algorithm::ends_with(_identifier.name, "_offset");
+ auto declarations = m_resolver.nameFromCurrentScope(_identifier.name.str());
+ bool isSlot = boost::algorithm::ends_with(_identifier.name.str(), "_slot");
+ bool isOffset = boost::algorithm::ends_with(_identifier.name.str(), "_offset");
if (isSlot || isOffset)
{
// special mode to access storage variables
if (!declarations.empty())
// the special identifier exists itself, we should not allow that.
return size_t(-1);
- string realName = _identifier.name.substr(0, _identifier.name.size() - (
+ string realName = _identifier.name.str().substr(0, _identifier.name.str().size() - (
isSlot ?
string("_slot").size() :
string("_offset").size()
diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp
index 569e5b0e..2d26ce8a 100644
--- a/libsolidity/ast/ASTJsonConverter.cpp
+++ b/libsolidity/ast/ASTJsonConverter.cpp
@@ -459,7 +459,7 @@ bool ASTJsonConverter::visit(InlineAssembly const& _node)
if (it.first)
{
Json::Value tuple(Json::objectValue);
- tuple[it.first->name] = inlineAssemblyIdentifierToJson(it);
+ tuple[it.first->name.str()] = inlineAssemblyIdentifierToJson(it);
externalReferences.append(tuple);
}
}
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index d5d11478..6c3863e6 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -1144,10 +1144,10 @@ TypePointer RationalNumberType::binaryOperatorResult(Token _operator, TypePointe
bigint denominator = optimizedPow(m_value.denominator(), absExp);
if (exp >= 0)
- value = rational(numerator, denominator);
+ value = makeRational(numerator, denominator);
else
// invert
- value = rational(denominator, numerator);
+ value = makeRational(denominator, numerator);
}
break;
}
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index b764717f..24ace447 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -51,6 +51,15 @@ using FunctionTypePointer = std::shared_ptr<FunctionType const>;
using TypePointers = std::vector<TypePointer>;
using rational = boost::rational<dev::bigint>;
+inline rational makeRational(bigint const& _numerator, bigint const& _denominator)
+{
+ solAssert(_denominator != 0, "division by zero");
+ // due to a bug in certain versions of boost the denominator has to be positive
+ if (_denominator < 0)
+ return rational(-_numerator, -_denominator);
+ else
+ return rational(_numerator, _denominator);
+}
enum class DataLocation { Storage, CallData, Memory };
diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp
index 210b613d..6e14d68a 100644
--- a/libsolidity/codegen/CompilerContext.cpp
+++ b/libsolidity/codegen/CompilerContext.cpp
@@ -32,6 +32,7 @@
#include <libsolidity/inlineasm/AsmCodeGen.h>
#include <libsolidity/inlineasm/AsmAnalysis.h>
#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
+#include <libyul/YulString.h>
#include <boost/algorithm/string/replace.hpp>
@@ -326,7 +327,7 @@ void CompilerContext::appendInlineAssembly(
bool
)
{
- auto it = std::find(_localVariables.begin(), _localVariables.end(), _identifier.name);
+ auto it = std::find(_localVariables.begin(), _localVariables.end(), _identifier.name.str());
return it == _localVariables.end() ? size_t(-1) : 1;
};
identifierAccess.generateCode = [&](
@@ -335,7 +336,7 @@ void CompilerContext::appendInlineAssembly(
yul::AbstractAssembly& _assembly
)
{
- auto it = std::find(_localVariables.begin(), _localVariables.end(), _identifier.name);
+ auto it = std::find(_localVariables.begin(), _localVariables.end(), _identifier.name.str());
solAssert(it != _localVariables.end(), "");
int stackDepth = _localVariables.end() - it;
int stackDiff = _assembly.stackHeight() - startStackHeight + stackDepth;
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index d89d023e..90eb74fe 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -1016,8 +1016,22 @@ void CompilerUtils::convertType(
}
else
{
- // All other types should not be convertible to non-equal types.
- solAssert(_typeOnStack == _targetType, "Invalid type conversion requested.");
+ if (stackTypeCategory == Type::Category::Function && targetTypeCategory == Type::Category::Function)
+ {
+ FunctionType const& typeOnStack = dynamic_cast<FunctionType const&>(_typeOnStack);
+ FunctionType const& targetType = dynamic_cast<FunctionType const&>(_targetType);
+ solAssert(
+ typeOnStack.isImplicitlyConvertibleTo(targetType) &&
+ typeOnStack.sizeOnStack() == targetType.sizeOnStack() &&
+ (typeOnStack.kind() == FunctionType::Kind::Internal || typeOnStack.kind() == FunctionType::Kind::External) &&
+ typeOnStack.kind() == targetType.kind(),
+ "Invalid function type conversion requested."
+ );
+ }
+ else
+ // All other types should not be convertible to non-equal types.
+ solAssert(_typeOnStack == _targetType, "Invalid type conversion requested.");
+
if (_cleanupNeeded && _targetType.canBeStored() && _targetType.storageBytes() < 32)
m_context
<< ((u256(1) << (8 * _targetType.storageBytes())) - 1)
diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp
index 04b5d1a8..ac019c06 100644
--- a/libsolidity/inlineasm/AsmAnalysis.cpp
+++ b/libsolidity/inlineasm/AsmAnalysis.cpp
@@ -79,17 +79,17 @@ bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction)
bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
{
- expectValidType(_literal.type, _literal.location);
+ expectValidType(_literal.type.str(), _literal.location);
++m_stackHeight;
- if (_literal.kind == assembly::LiteralKind::String && _literal.value.size() > 32)
+ if (_literal.kind == assembly::LiteralKind::String && _literal.value.str().size() > 32)
{
m_errorReporter.typeError(
_literal.location,
- "String literal too long (" + to_string(_literal.value.size()) + " > 32)"
+ "String literal too long (" + to_string(_literal.value.str().size()) + " > 32)"
);
return false;
}
- else if (_literal.kind == assembly::LiteralKind::Number && bigint(_literal.value) > u256(-1))
+ else if (_literal.kind == assembly::LiteralKind::Number && bigint(_literal.value.str()) > u256(-1))
{
m_errorReporter.typeError(
_literal.location,
@@ -100,7 +100,7 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
else if (_literal.kind == assembly::LiteralKind::Boolean)
{
solAssert(m_flavour == AsmFlavour::Yul, "");
- solAssert(_literal.value == "true" || _literal.value == "false", "");
+ solAssert(_literal.value == YulString{string("true")} || _literal.value == YulString{string("false")}, "");
}
m_info.stackHeightInfo[&_literal] = m_stackHeight;
return true;
@@ -118,7 +118,7 @@ bool AsmAnalyzer::operator()(assembly::Identifier const& _identifier)
{
m_errorReporter.declarationError(
_identifier.location,
- "Variable " + _identifier.name + " used before it was declared."
+ "Variable " + _identifier.name.str() + " used before it was declared."
);
success = false;
}
@@ -132,7 +132,7 @@ bool AsmAnalyzer::operator()(assembly::Identifier const& _identifier)
{
m_errorReporter.typeError(
_identifier.location,
- "Function " + _identifier.name + " used without being called."
+ "Function " + _identifier.name.str() + " used without being called."
);
success = false;
}
@@ -253,7 +253,7 @@ bool AsmAnalyzer::operator()(assembly::VariableDeclaration const& _varDecl)
for (auto const& variable: _varDecl.variables)
{
- expectValidType(variable.type, variable.location);
+ expectValidType(variable.type.str(), variable.location);
m_activeVariables.insert(&boost::get<Scope::Variable>(m_currentScope->identifiers.at(variable.name)));
}
m_info.stackHeightInfo[&_varDecl] = m_stackHeight;
@@ -268,7 +268,7 @@ bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef)
Scope& varScope = scope(virtualBlock);
for (auto const& var: _funDef.parameters + _funDef.returnVariables)
{
- expectValidType(var.type, var.location);
+ expectValidType(var.type.str(), var.location);
m_activeVariables.insert(&boost::get<Scope::Variable>(varScope.identifiers.at(var.name)));
}
@@ -361,7 +361,7 @@ bool AsmAnalyzer::operator()(Switch const& _switch)
if (!expectExpression(*_switch.expression))
success = false;
- set<tuple<LiteralKind, string>> cases;
+ set<tuple<LiteralKind, YulString>> cases;
for (auto const& _case: _switch.cases)
{
if (_case.value)
@@ -503,7 +503,7 @@ bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t
{
m_errorReporter.declarationError(
_variable.location,
- "Variable " + _variable.name + " used before it was declared."
+ "Variable " + _variable.name.str() + " used before it was declared."
);
success = false;
}
diff --git a/libsolidity/inlineasm/AsmData.h b/libsolidity/inlineasm/AsmData.h
index 2982d5e0..a8d5e327 100644
--- a/libsolidity/inlineasm/AsmData.h
+++ b/libsolidity/inlineasm/AsmData.h
@@ -27,7 +27,13 @@
#include <libevmasm/Instruction.h>
#include <libevmasm/SourceLocation.h>
+#include <libyul/YulString.h>
+
#include <boost/variant.hpp>
+#include <boost/noncopyable.hpp>
+
+#include <map>
+#include <memory>
namespace dev
{
@@ -36,20 +42,21 @@ namespace solidity
namespace assembly
{
-using Type = std::string;
+using YulString = dev::yul::YulString;
+using Type = YulString;
-struct TypedName { SourceLocation location; std::string name; Type type; };
+struct TypedName { SourceLocation location; YulString name; Type type; };
using TypedNameList = std::vector<TypedName>;
/// Direct EVM instruction (except PUSHi and JUMPDEST)
struct Instruction { SourceLocation location; solidity::Instruction instruction; };
/// Literal number or string (up to 32 bytes)
enum class LiteralKind { Number, Boolean, String };
-struct Literal { SourceLocation location; LiteralKind kind; std::string value; Type type; };
+struct Literal { SourceLocation location; LiteralKind kind; YulString value; Type type; };
/// External / internal identifier or label reference
-struct Identifier { SourceLocation location; std::string name; };
+struct Identifier { SourceLocation location; YulString name; };
/// Jump label ("name:")
-struct Label { SourceLocation location; std::string name; };
+struct Label { SourceLocation location; YulString name; };
/// Assignment from stack (":= x", moves stack top into x, potentially multiple slots)
struct StackAssignment { SourceLocation location; Identifier variableName; };
/// Assignment ("x := mload(20:u256)", expects push-1-expression on the right hand
@@ -69,7 +76,7 @@ struct VariableDeclaration { SourceLocation location; TypedNameList variables; s
/// Block that creates a scope (frees declared stack variables)
struct Block { SourceLocation location; std::vector<Statement> statements; };
/// Function definition ("function f(a, b) -> (d, e) { ... }")
-struct FunctionDefinition { SourceLocation location; std::string name; TypedNameList parameters; TypedNameList returnVariables; Block body; };
+struct FunctionDefinition { SourceLocation location; YulString name; TypedNameList parameters; TypedNameList returnVariables; Block body; };
/// Conditional execution without "else" part.
struct If { SourceLocation location; std::shared_ptr<Expression> condition; Block body; };
/// Switch case or default case
diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp
index 54cdc1c6..1f399edc 100644
--- a/libsolidity/inlineasm/AsmParser.cpp
+++ b/libsolidity/inlineasm/AsmParser.cpp
@@ -112,8 +112,8 @@ assembly::Statement Parser::parseStatement()
advance();
expectToken(Token::Colon);
assignment.variableName.location = location();
- assignment.variableName.name = currentLiteral();
- if (instructions().count(assignment.variableName.name))
+ assignment.variableName.name = YulString(currentLiteral());
+ if (instructions().count(assignment.variableName.name.str()))
fatalParserError("Identifier expected, got instruction name.");
assignment.location.end = endPosition();
expectToken(Token::Identifier);
@@ -173,7 +173,7 @@ assembly::Statement Parser::parseStatement()
if (currentToken() == Token::Assign && peekNextToken() != Token::Colon)
{
assembly::Assignment assignment = createWithLocation<assembly::Assignment>(identifier.location);
- if (m_flavour != AsmFlavour::Yul && instructions().count(identifier.name))
+ if (m_flavour != AsmFlavour::Yul && instructions().count(identifier.name.str()))
fatalParserError("Cannot use instruction names for identifier names.");
advance();
assignment.variableNames.emplace_back(identifier);
@@ -363,7 +363,7 @@ Parser::ElementaryOperation Parser::parseElementaryOperation()
ret = Instruction{location(), instr};
}
else
- ret = Identifier{location(), literal};
+ ret = Identifier{location(), YulString{literal}};
advance();
break;
}
@@ -394,15 +394,15 @@ Parser::ElementaryOperation Parser::parseElementaryOperation()
Literal literal{
location(),
kind,
- currentLiteral(),
- ""
+ YulString{currentLiteral()},
+ {}
};
advance();
if (m_flavour == AsmFlavour::Yul)
{
expectToken(Token::Colon);
literal.location.end = endPosition();
- literal.type = expectAsmIdentifier();
+ literal.type = YulString{expectAsmIdentifier()};
}
else if (kind == LiteralKind::Boolean)
fatalParserError("True and false are not valid literals.");
@@ -449,7 +449,7 @@ assembly::FunctionDefinition Parser::parseFunctionDefinition()
RecursionGuard recursionGuard(*this);
FunctionDefinition funDef = createWithLocation<FunctionDefinition>();
expectToken(Token::Function);
- funDef.name = expectAsmIdentifier();
+ funDef.name = YulString{expectAsmIdentifier()};
expectToken(Token::LParen);
while (currentToken() != Token::RParen)
{
@@ -564,12 +564,12 @@ TypedName Parser::parseTypedName()
{
RecursionGuard recursionGuard(*this);
TypedName typedName = createWithLocation<TypedName>();
- typedName.name = expectAsmIdentifier();
+ typedName.name = YulString{expectAsmIdentifier()};
if (m_flavour == AsmFlavour::Yul)
{
expectToken(Token::Colon);
typedName.location.end = endPosition();
- typedName.type = expectAsmIdentifier();
+ typedName.type = YulString{expectAsmIdentifier()};
}
return typedName;
}
diff --git a/libsolidity/inlineasm/AsmPrinter.cpp b/libsolidity/inlineasm/AsmPrinter.cpp
index 4b8c9538..ae0bd1eb 100644
--- a/libsolidity/inlineasm/AsmPrinter.cpp
+++ b/libsolidity/inlineasm/AsmPrinter.cpp
@@ -52,17 +52,17 @@ string AsmPrinter::operator()(assembly::Literal const& _literal)
switch (_literal.kind)
{
case LiteralKind::Number:
- solAssert(isValidDecimal(_literal.value) || isValidHex(_literal.value), "Invalid number literal");
- return _literal.value + appendTypeName(_literal.type);
+ solAssert(isValidDecimal(_literal.value.str()) || isValidHex(_literal.value.str()), "Invalid number literal");
+ return _literal.value.str() + appendTypeName(_literal.type);
case LiteralKind::Boolean:
- solAssert(_literal.value == "true" || _literal.value == "false", "Invalid bool literal.");
- return ((_literal.value == "true") ? "true" : "false") + appendTypeName(_literal.type);
+ solAssert(_literal.value.str() == "true" || _literal.value.str() == "false", "Invalid bool literal.");
+ return ((_literal.value.str() == "true") ? "true" : "false") + appendTypeName(_literal.type);
case LiteralKind::String:
break;
}
string out;
- for (char c: _literal.value)
+ for (char c: _literal.value.str())
if (c == '\\')
out += "\\\\";
else if (c == '"')
@@ -93,7 +93,7 @@ string AsmPrinter::operator()(assembly::Literal const& _literal)
string AsmPrinter::operator()(assembly::Identifier const& _identifier)
{
solAssert(!_identifier.name.empty(), "Invalid identifier.");
- return _identifier.name;
+ return _identifier.name.str();
}
string AsmPrinter::operator()(assembly::FunctionalInstruction const& _functionalInstruction)
@@ -118,7 +118,7 @@ string AsmPrinter::operator()(assembly::Label const& _label)
{
solAssert(!m_yul, "");
solAssert(!_label.name.empty(), "Invalid label.");
- return _label.name + ":";
+ return _label.name.str() + ":";
}
string AsmPrinter::operator()(assembly::StackAssignment const& _assignment)
@@ -157,7 +157,7 @@ string AsmPrinter::operator()(assembly::VariableDeclaration const& _variableDecl
string AsmPrinter::operator()(assembly::FunctionDefinition const& _functionDefinition)
{
solAssert(!_functionDefinition.name.empty(), "Invalid function name.");
- string out = "function " + _functionDefinition.name + "(";
+ string out = "function " + _functionDefinition.name.str() + "(";
out += boost::algorithm::join(
_functionDefinition.parameters | boost::adaptors::transformed(
[this](TypedName argument) { return formatTypedName(argument); }
@@ -239,12 +239,12 @@ string AsmPrinter::operator()(Block const& _block)
string AsmPrinter::formatTypedName(TypedName _variable) const
{
solAssert(!_variable.name.empty(), "Invalid variable name.");
- return _variable.name + appendTypeName(_variable.type);
+ return _variable.name.str() + appendTypeName(_variable.type);
}
-string AsmPrinter::appendTypeName(std::string const& _type) const
+string AsmPrinter::appendTypeName(YulString _type) const
{
if (m_yul)
- return ":" + _type;
+ return ":" + _type.str();
return "";
}
diff --git a/libsolidity/inlineasm/AsmPrinter.h b/libsolidity/inlineasm/AsmPrinter.h
index 971822bf..72048975 100644
--- a/libsolidity/inlineasm/AsmPrinter.h
+++ b/libsolidity/inlineasm/AsmPrinter.h
@@ -24,6 +24,8 @@
#include <libsolidity/inlineasm/AsmDataForward.h>
+#include <libyul/YulString.h>
+
#include <boost/variant.hpp>
namespace dev
@@ -56,7 +58,7 @@ public:
private:
std::string formatTypedName(TypedName _variable) const;
- std::string appendTypeName(std::string const& _type) const;
+ std::string appendTypeName(yul::YulString _type) const;
bool m_yul = false;
};
diff --git a/libsolidity/inlineasm/AsmScope.cpp b/libsolidity/inlineasm/AsmScope.cpp
index af81b301..019170ca 100644
--- a/libsolidity/inlineasm/AsmScope.cpp
+++ b/libsolidity/inlineasm/AsmScope.cpp
@@ -24,7 +24,7 @@ using namespace std;
using namespace dev::solidity::assembly;
-bool Scope::registerLabel(string const& _name)
+bool Scope::registerLabel(yul::YulString _name)
{
if (exists(_name))
return false;
@@ -32,7 +32,7 @@ bool Scope::registerLabel(string const& _name)
return true;
}
-bool Scope::registerVariable(string const& _name, YulType const& _type)
+bool Scope::registerVariable(yul::YulString _name, YulType const& _type)
{
if (exists(_name))
return false;
@@ -42,7 +42,7 @@ bool Scope::registerVariable(string const& _name, YulType const& _type)
return true;
}
-bool Scope::registerFunction(string const& _name, std::vector<YulType> const& _arguments, std::vector<YulType> const& _returns)
+bool Scope::registerFunction(yul::YulString _name, std::vector<YulType> const& _arguments, std::vector<YulType> const& _returns)
{
if (exists(_name))
return false;
@@ -50,7 +50,7 @@ bool Scope::registerFunction(string const& _name, std::vector<YulType> const& _a
return true;
}
-Scope::Identifier* Scope::lookup(string const& _name)
+Scope::Identifier* Scope::lookup(yul::YulString _name)
{
bool crossedFunctionBoundary = false;
for (Scope* s = this; s; s = s->superScope)
@@ -70,7 +70,7 @@ Scope::Identifier* Scope::lookup(string const& _name)
return nullptr;
}
-bool Scope::exists(string const& _name) const
+bool Scope::exists(yul::YulString _name) const
{
if (identifiers.count(_name))
return true;
diff --git a/libsolidity/inlineasm/AsmScope.h b/libsolidity/inlineasm/AsmScope.h
index fc674e71..65848018 100644
--- a/libsolidity/inlineasm/AsmScope.h
+++ b/libsolidity/inlineasm/AsmScope.h
@@ -22,6 +22,8 @@
#include <libsolidity/interface/Exceptions.h>
+#include <libyul/YulString.h>
+
#include <libdevcore/Visitor.h>
#include <boost/variant.hpp>
@@ -39,7 +41,7 @@ namespace assembly
struct Scope
{
- using YulType = std::string;
+ using YulType = yul::YulString;
using LabelID = size_t;
struct Variable { YulType type; };
@@ -54,10 +56,10 @@ struct Scope
using Visitor = GenericVisitor<Variable const, Label const, Function const>;
using NonconstVisitor = GenericVisitor<Variable, Label, Function>;
- bool registerVariable(std::string const& _name, YulType const& _type);
- bool registerLabel(std::string const& _name);
+ bool registerVariable(yul::YulString _name, YulType const& _type);
+ bool registerLabel(yul::YulString _name);
bool registerFunction(
- std::string const& _name,
+ yul::YulString _name,
std::vector<YulType> const& _arguments,
std::vector<YulType> const& _returns
);
@@ -67,12 +69,12 @@ struct Scope
/// will any lookups across assembly boundaries.
/// The pointer will be invalidated if the scope is modified.
/// @param _crossedFunction if true, we already crossed a function boundary during recursive lookup
- Identifier* lookup(std::string const& _name);
+ Identifier* lookup(yul::YulString _name);
/// Looks up the identifier in this and super scopes (will not find variables across function
/// boundaries and generally stops at assembly boundaries) and calls the visitor, returns
/// false if not found.
template <class V>
- bool lookup(std::string const& _name, V const& _visitor)
+ bool lookup(yul::YulString _name, V const& _visitor)
{
if (Identifier* id = lookup(_name))
{
@@ -84,7 +86,7 @@ struct Scope
}
/// @returns true if the name exists in this scope or in super scopes (also searches
/// across function and assembly boundaries).
- bool exists(std::string const& _name) const;
+ bool exists(yul::YulString _name) const;
/// @returns the number of variables directly registered inside the scope.
size_t numberOfVariables() const;
@@ -95,7 +97,7 @@ struct Scope
/// If true, variables from the super scope are not visible here (other identifiers are),
/// but they are still taken into account to prevent shadowing.
bool functionScope = false;
- std::map<std::string, Identifier> identifiers;
+ std::map<yul::YulString, Identifier> identifiers;
};
}
diff --git a/libsolidity/inlineasm/AsmScopeFiller.cpp b/libsolidity/inlineasm/AsmScopeFiller.cpp
index 2d15c820..d1f98083 100644
--- a/libsolidity/inlineasm/AsmScopeFiller.cpp
+++ b/libsolidity/inlineasm/AsmScopeFiller.cpp
@@ -57,7 +57,7 @@ bool ScopeFiller::operator()(Label const& _item)
//@TODO secondary location
m_errorReporter.declarationError(
_item.location,
- "Label name " + _item.name + " already taken in this scope."
+ "Label name " + _item.name.str() + " already taken in this scope."
);
return false;
}
@@ -77,16 +77,16 @@ bool ScopeFiller::operator()(assembly::FunctionDefinition const& _funDef)
bool success = true;
vector<Scope::YulType> arguments;
for (auto const& _argument: _funDef.parameters)
- arguments.push_back(_argument.type);
+ arguments.emplace_back(_argument.type.str());
vector<Scope::YulType> returns;
for (auto const& _return: _funDef.returnVariables)
- returns.push_back(_return.type);
+ returns.emplace_back(_return.type.str());
if (!m_currentScope->registerFunction(_funDef.name, arguments, returns))
{
//@TODO secondary location
m_errorReporter.declarationError(
_funDef.location,
- "Function name " + _funDef.name + " already taken in this scope."
+ "Function name " + _funDef.name.str() + " already taken in this scope."
);
success = false;
}
@@ -164,7 +164,7 @@ bool ScopeFiller::registerVariable(TypedName const& _name, SourceLocation const&
//@TODO secondary location
m_errorReporter.declarationError(
_location,
- "Variable name " + _name.name + " already taken in this scope."
+ "Variable name " + _name.name.str() + " already taken in this scope."
);
return false;
}
diff --git a/libsolidity/interface/Version.cpp b/libsolidity/interface/Version.cpp
index a35bfd29..b5f68ce8 100644
--- a/libsolidity/interface/Version.cpp
+++ b/libsolidity/interface/Version.cpp
@@ -55,13 +55,13 @@ bytes dev::solidity::binaryVersion()
ret = ret * 10 + (VersionString[i] - '0');
return ret;
};
- ret.push_back(byte(parseDecimal()));
+ ret.push_back(uint8_t(parseDecimal()));
solAssert(i < VersionString.size() && VersionString[i] == '.', "");
++i;
- ret.push_back(byte(parseDecimal()));
+ ret.push_back(uint8_t(parseDecimal()));
solAssert(i < VersionString.size() && VersionString[i] == '.', "");
++i;
- ret.push_back(byte(parseDecimal()));
+ ret.push_back(uint8_t(parseDecimal()));
solAssert(i < VersionString.size() && (VersionString[i] == '-' || VersionString[i] == '+'), "");
++i;
size_t commitpos = VersionString.find("commit.");
diff --git a/libyul/ASTDataForward.h b/libyul/ASTDataForward.h
index 7f131b5e..8c49e68f 100644
--- a/libyul/ASTDataForward.h
+++ b/libyul/ASTDataForward.h
@@ -46,6 +46,7 @@ using ExpressionStatement = solidity::assembly::ExpressionStatement;
using Block = solidity::assembly::Block;
using TypedName = solidity::assembly::TypedName;
+class YulString;
using Expression = boost::variant<FunctionalInstruction, FunctionCall, Identifier, Literal>;
using Statement = boost::variant<ExpressionStatement, Instruction, Label, StackAssignment, Assignment, VariableDeclaration, FunctionDefinition, If, Switch, ForLoop, Block>;
diff --git a/libyul/YulString.h b/libyul/YulString.h
new file mode 100644
index 00000000..ae01c83f
--- /dev/null
+++ b/libyul/YulString.h
@@ -0,0 +1,96 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ 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.
+
+ solidity is distributed in the hope that it will be useful,
+ 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
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * String abstraction that avoids copies.
+ */
+
+#pragma once
+
+#include <boost/noncopyable.hpp>
+
+#include <map>
+#include <memory>
+#include <vector>
+#include <string>
+
+namespace dev
+{
+namespace yul
+{
+
+class YulStringRepository: boost::noncopyable
+{
+public:
+ YulStringRepository(): m_strings{std::make_shared<std::string>()}
+ {
+ m_ids[std::string{}] = 0;
+ }
+ static YulStringRepository& instance()
+ {
+ static YulStringRepository inst;
+ return inst;
+ }
+ size_t stringToId(std::string const& _string)
+ {
+ if (_string.empty())
+ return 0;
+ size_t& id = m_ids[_string];
+ if (id == 0)
+ {
+ m_strings.emplace_back(std::make_shared<std::string>(_string));
+ id = m_strings.size() - 1;
+ }
+ return id;
+ }
+ std::string const& idToString(size_t _id) const
+ {
+ return *m_strings.at(_id);
+ }
+
+private:
+ std::vector<std::shared_ptr<std::string>> m_strings;
+ std::map<std::string, size_t> m_ids;
+};
+
+class YulString
+{
+public:
+ YulString() = default;
+ explicit YulString(std::string const& _s): m_id(YulStringRepository::instance().stringToId(_s)) {}
+ YulString(YulString const&) = default;
+ YulString(YulString&&) = default;
+ YulString& operator=(YulString const&) = default;
+ YulString& operator=(YulString&&) = default;
+
+ /// This is not consistent with the string <-operator!
+ bool operator<(YulString const& _other) const { return m_id < _other.m_id; }
+ bool operator==(YulString const& _other) const { return m_id == _other.m_id; }
+ bool operator!=(YulString const& _other) const { return m_id != _other.m_id; }
+
+ bool empty() const { return m_id == 0; }
+ std::string const& str() const
+ {
+ return YulStringRepository::instance().idToString(m_id);
+ }
+
+private:
+ /// ID of the string. Assumes that the empty string has ID zero.
+ size_t m_id = 0;
+};
+
+}
+}
diff --git a/libyul/backends/evm/EVMAssembly.cpp b/libyul/backends/evm/EVMAssembly.cpp
index b2f0878f..b37a3231 100644
--- a/libyul/backends/evm/EVMAssembly.cpp
+++ b/libyul/backends/evm/EVMAssembly.cpp
@@ -44,7 +44,7 @@ void EVMAssembly::setSourceLocation(SourceLocation const&)
void EVMAssembly::appendInstruction(solidity::Instruction _instr)
{
- m_bytecode.push_back(byte(_instr));
+ m_bytecode.push_back(uint8_t(_instr));
m_stackHeight += solidity::instructionInfo(_instr).ret - solidity::instructionInfo(_instr).args;
}
@@ -101,7 +101,7 @@ void EVMAssembly::appendJumpTo(LabelID _labelId, int _stackDiffAfter)
{
if (m_evm15)
{
- m_bytecode.push_back(byte(solidity::Instruction::JUMPTO));
+ m_bytecode.push_back(uint8_t(solidity::Instruction::JUMPTO));
appendLabelReferenceInternal(_labelId);
m_stackHeight += _stackDiffAfter;
}
@@ -116,7 +116,7 @@ void EVMAssembly::appendJumpToIf(LabelID _labelId)
{
if (m_evm15)
{
- m_bytecode.push_back(byte(solidity::Instruction::JUMPIF));
+ m_bytecode.push_back(uint8_t(solidity::Instruction::JUMPIF));
appendLabelReferenceInternal(_labelId);
m_stackHeight--;
}
@@ -132,7 +132,7 @@ void EVMAssembly::appendBeginsub(LabelID _labelId, int _arguments)
solAssert(m_evm15, "BEGINSUB used for EVM 1.0");
solAssert(_arguments >= 0, "");
setLabelToCurrentPosition(_labelId);
- m_bytecode.push_back(byte(solidity::Instruction::BEGINSUB));
+ m_bytecode.push_back(uint8_t(solidity::Instruction::BEGINSUB));
m_stackHeight += _arguments;
}
@@ -140,7 +140,7 @@ void EVMAssembly::appendJumpsub(LabelID _labelId, int _arguments, int _returns)
{
solAssert(m_evm15, "JUMPSUB used for EVM 1.0");
solAssert(_arguments >= 0 && _returns >= 0, "");
- m_bytecode.push_back(byte(solidity::Instruction::JUMPSUB));
+ m_bytecode.push_back(uint8_t(solidity::Instruction::JUMPSUB));
appendLabelReferenceInternal(_labelId);
m_stackHeight += _returns - _arguments;
}
@@ -149,7 +149,7 @@ void EVMAssembly::appendReturnsub(int _returns, int _stackDiffAfter)
{
solAssert(m_evm15, "RETURNSUB used for EVM 1.0");
solAssert(_returns >= 0, "");
- m_bytecode.push_back(byte(solidity::Instruction::RETURNSUB));
+ m_bytecode.push_back(uint8_t(solidity::Instruction::RETURNSUB));
m_stackHeight += _stackDiffAfter - _returns;
}
@@ -198,5 +198,5 @@ void EVMAssembly::updateReference(size_t pos, size_t size, u256 value)
solAssert(m_bytecode.size() >= size && pos <= m_bytecode.size() - size, "");
solAssert(value < (u256(1) << (8 * size)), "");
for (size_t i = 0; i < size; i++)
- m_bytecode[pos + i] = byte((value >> (8 * (size - i - 1))) & 0xff);
+ m_bytecode[pos + i] = uint8_t((value >> (8 * (size - i - 1))) & 0xff);
}
diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp
index 89086b4e..650a8c0a 100644
--- a/libyul/backends/evm/EVMCodeTransform.cpp
+++ b/libyul/backends/evm/EVMCodeTransform.cpp
@@ -201,18 +201,18 @@ void CodeTransform::operator()(assembly::Literal const& _literal)
{
m_assembly.setSourceLocation(_literal.location);
if (_literal.kind == assembly::LiteralKind::Number)
- m_assembly.appendConstant(u256(_literal.value));
+ m_assembly.appendConstant(u256(_literal.value.str()));
else if (_literal.kind == assembly::LiteralKind::Boolean)
{
- if (_literal.value == "true")
+ if (_literal.value.str() == "true")
m_assembly.appendConstant(u256(1));
else
m_assembly.appendConstant(u256(0));
}
else
{
- solAssert(_literal.value.size() <= 32, "");
- m_assembly.appendConstant(u256(h256(_literal.value, h256::FromBinary, h256::AlignLeft)));
+ solAssert(_literal.value.str().size() <= 32, "");
+ m_assembly.appendConstant(u256(h256(_literal.value.str(), h256::FromBinary, h256::AlignLeft)));
}
checkStackHeight(&_literal);
}
@@ -454,13 +454,13 @@ AbstractAssembly::LabelID CodeTransform::labelID(Scope::Label const& _label)
return m_context->labelIDs[&_label];
}
-AbstractAssembly::LabelID CodeTransform::functionEntryID(string const& _name, Scope::Function const& _function)
+AbstractAssembly::LabelID CodeTransform::functionEntryID(YulString _name, Scope::Function const& _function)
{
if (!m_context->functionEntryIDs.count(&_function))
{
AbstractAssembly::LabelID id =
m_useNamedLabelsForFunctions ?
- m_assembly.namedLabel(_name) :
+ m_assembly.namedLabel(_name.str()) :
m_assembly.newLabelId();
m_context->functionEntryIDs[&_function] = id;
}
diff --git a/libyul/backends/evm/EVMCodeTransform.h b/libyul/backends/evm/EVMCodeTransform.h
index 22ebbf43..c0de8ad6 100644
--- a/libyul/backends/evm/EVMCodeTransform.h
+++ b/libyul/backends/evm/EVMCodeTransform.h
@@ -117,7 +117,7 @@ private:
/// @returns the label ID corresponding to the given label, allocating a new one if
/// necessary.
AbstractAssembly::LabelID labelID(solidity::assembly::Scope::Label const& _label);
- AbstractAssembly::LabelID functionEntryID(std::string const& _name, solidity::assembly::Scope::Function const& _function);
+ AbstractAssembly::LabelID functionEntryID(YulString _name, solidity::assembly::Scope::Function const& _function);
/// Generates code for an expression that is supposed to return a single value.
void visitExpression(Expression const& _expression);
diff --git a/libyul/optimiser/ASTCopier.cpp b/libyul/optimiser/ASTCopier.cpp
index 4b7f21f8..d0c8dd45 100644
--- a/libyul/optimiser/ASTCopier.cpp
+++ b/libyul/optimiser/ASTCopier.cpp
@@ -111,14 +111,14 @@ Statement ASTCopier::operator()(Switch const& _switch)
Statement ASTCopier::operator()(FunctionDefinition const& _function)
{
- string translatedName = translateIdentifier(_function.name);
+ YulString translatedName = translateIdentifier(_function.name);
enterFunction(_function);
ScopeGuard g([&]() { this->leaveFunction(_function); });
return FunctionDefinition{
_function.location,
- move(translatedName),
+ translatedName,
translateVector(_function.parameters),
translateVector(_function.returnVariables),
translate(_function.body)
diff --git a/libyul/optimiser/ASTCopier.h b/libyul/optimiser/ASTCopier.h
index 13369cef..b6aceee3 100644
--- a/libyul/optimiser/ASTCopier.h
+++ b/libyul/optimiser/ASTCopier.h
@@ -22,6 +22,8 @@
#include <libyul/ASTDataForward.h>
+#include <libyul/YulString.h>
+
#include <boost/variant.hpp>
#include <boost/optional.hpp>
@@ -107,7 +109,7 @@ protected:
virtual void leaveScope(Block const&) { }
virtual void enterFunction(FunctionDefinition const&) { }
virtual void leaveFunction(FunctionDefinition const&) { }
- virtual std::string translateIdentifier(std::string const& _name) { return _name; }
+ virtual YulString translateIdentifier(YulString _name) { return _name; }
};
template <typename T>
diff --git a/libyul/optimiser/ASTWalker.h b/libyul/optimiser/ASTWalker.h
index 41617d55..38cb85ea 100644
--- a/libyul/optimiser/ASTWalker.h
+++ b/libyul/optimiser/ASTWalker.h
@@ -23,6 +23,7 @@
#include <libyul/ASTDataForward.h>
#include <libyul/Exceptions.h>
+#include <libyul/YulString.h>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp
index 51737097..64605362 100644
--- a/libyul/optimiser/CommonSubexpressionEliminator.cpp
+++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp
@@ -43,13 +43,13 @@ void CommonSubexpressionEliminator::visit(Expression& _e)
if (_e.type() == typeid(Identifier))
{
Identifier& identifier = boost::get<Identifier>(_e);
- string const& name = identifier.name;
+ YulString name = identifier.name;
if (m_value.count(name))
{
assertThrow(m_value.at(name), OptimizerException, "");
if (m_value.at(name)->type() == typeid(Identifier))
{
- string const& value = boost::get<Identifier>(*m_value.at(name)).name;
+ YulString value = boost::get<Identifier>(*m_value.at(name)).name;
assertThrow(inScope(value), OptimizerException, "");
_e = Identifier{locationOf(_e), value};
}
diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp
index 7ac42c30..1ff1d2f0 100644
--- a/libyul/optimiser/DataFlowAnalyzer.cpp
+++ b/libyul/optimiser/DataFlowAnalyzer.cpp
@@ -38,9 +38,9 @@ using namespace dev::yul;
void DataFlowAnalyzer::operator()(Assignment& _assignment)
{
- set<string> names;
+ set<YulString> names;
for (auto const& var: _assignment.variableNames)
- names.insert(var.name);
+ names.emplace(var.name);
assertThrow(_assignment.value, OptimizerException, "");
visit(*_assignment.value);
handleAssignment(names, _assignment.value.get());
@@ -48,9 +48,9 @@ void DataFlowAnalyzer::operator()(Assignment& _assignment)
void DataFlowAnalyzer::operator()(VariableDeclaration& _varDecl)
{
- set<string> names;
+ set<YulString> names;
for (auto const& var: _varDecl.variables)
- names.insert(var.name);
+ names.emplace(var.name);
m_variableScopes.back().variables += names;
if (_varDecl.value)
visit(*_varDecl.value);
@@ -69,7 +69,7 @@ void DataFlowAnalyzer::operator()(If& _if)
void DataFlowAnalyzer::operator()(Switch& _switch)
{
visit(*_switch.expression);
- set<string> assignedVariables;
+ set<YulString> assignedVariables;
for (auto& _case: _switch.cases)
{
(*this)(_case.body);
@@ -86,9 +86,9 @@ void DataFlowAnalyzer::operator()(FunctionDefinition& _fun)
{
pushScope(true);
for (auto const& parameter: _fun.parameters)
- m_variableScopes.back().variables.insert(parameter.name);
+ m_variableScopes.back().variables.emplace(parameter.name);
for (auto const& var: _fun.returnVariables)
- m_variableScopes.back().variables.insert(var.name);
+ m_variableScopes.back().variables.emplace(var.name);
ASTModifier::operator()(_fun);
popScope();
}
@@ -122,7 +122,7 @@ void DataFlowAnalyzer::operator()(Block& _block)
assertThrow(numScopes == m_variableScopes.size(), OptimizerException, "");
}
-void DataFlowAnalyzer::handleAssignment(set<string> const& _variables, Expression* _value)
+void DataFlowAnalyzer::handleAssignment(set<YulString> const& _variables, Expression* _value)
{
clearValues(_variables);
@@ -131,7 +131,7 @@ void DataFlowAnalyzer::handleAssignment(set<string> const& _variables, Expressio
movableChecker.visit(*_value);
if (_variables.size() == 1)
{
- string const& name = *_variables.begin();
+ YulString name = *_variables.begin();
// Expression has to be movable and cannot contain a reference
// to the variable that will be assigned to.
if (_value && movableChecker.movable() && !movableChecker.referencedVariables().count(name))
@@ -143,7 +143,7 @@ void DataFlowAnalyzer::handleAssignment(set<string> const& _variables, Expressio
{
m_references[name] = referencedVariables;
for (auto const& ref: referencedVariables)
- m_referencedBy[ref].insert(name);
+ m_referencedBy[ref].emplace(name);
}
}
@@ -158,7 +158,7 @@ void DataFlowAnalyzer::popScope()
m_variableScopes.pop_back();
}
-void DataFlowAnalyzer::clearValues(set<string> _variables)
+void DataFlowAnalyzer::clearValues(set<YulString> _variables)
{
// All variables that reference variables to be cleared also have to be
// cleared, but not recursively, since only the value of the original
@@ -176,7 +176,7 @@ void DataFlowAnalyzer::clearValues(set<string> _variables)
// Clear variables that reference variables to be cleared.
for (auto const& name: _variables)
for (auto const& ref: m_referencedBy[name])
- _variables.insert(ref);
+ _variables.emplace(ref);
// Clear the value and update the reference relation.
for (auto const& name: _variables)
@@ -189,7 +189,7 @@ void DataFlowAnalyzer::clearValues(set<string> _variables)
}
}
-bool DataFlowAnalyzer::inScope(string const& _variableName) const
+bool DataFlowAnalyzer::inScope(YulString _variableName) const
{
for (auto const& scope: m_variableScopes | boost::adaptors::reversed)
{
diff --git a/libyul/optimiser/DataFlowAnalyzer.h b/libyul/optimiser/DataFlowAnalyzer.h
index 95671467..a0c21eee 100644
--- a/libyul/optimiser/DataFlowAnalyzer.h
+++ b/libyul/optimiser/DataFlowAnalyzer.h
@@ -24,7 +24,8 @@
#include <libyul/optimiser/ASTWalker.h>
-#include <string>
+#include <libyul/YulString.h>
+
#include <map>
#include <set>
@@ -54,7 +55,7 @@ public:
protected:
/// Registers the assignment.
- void handleAssignment(std::set<std::string> const& _names, Expression* _value);
+ void handleAssignment(std::set<YulString> const& _names, Expression* _value);
/// Creates a new inner scope.
void pushScope(bool _functionScope);
@@ -64,22 +65,22 @@ protected:
/// Clears information about the values assigned to the given variables,
/// for example at points where control flow is merged.
- void clearValues(std::set<std::string> _names);
+ void clearValues(std::set<YulString> _names);
/// Returns true iff the variable is in scope.
- bool inScope(std::string const& _variableName) const;
+ bool inScope(YulString _variableName) const;
/// Current values of variables, always movable.
- std::map<std::string, Expression const*> m_value;
+ std::map<YulString, Expression const*> m_value;
/// m_references[a].contains(b) <=> the current expression assigned to a references b
- std::map<std::string, std::set<std::string>> m_references;
+ std::map<YulString, std::set<YulString>> m_references;
/// m_referencedBy[b].contains(a) <=> the current expression assigned to a references b
- std::map<std::string, std::set<std::string>> m_referencedBy;
+ std::map<YulString, std::set<YulString>> m_referencedBy;
struct Scope
{
explicit Scope(bool _isFunction): isFunction(_isFunction) {}
- std::set<std::string> variables;
+ std::set<YulString> variables;
bool isFunction;
};
/// List of scopes.
diff --git a/libyul/optimiser/Disambiguator.cpp b/libyul/optimiser/Disambiguator.cpp
index dcba97c9..4303f412 100644
--- a/libyul/optimiser/Disambiguator.cpp
+++ b/libyul/optimiser/Disambiguator.cpp
@@ -32,7 +32,7 @@ using namespace dev::solidity;
using Scope = dev::solidity::assembly::Scope;
-string Disambiguator::translateIdentifier(string const& _originalName)
+YulString Disambiguator::translateIdentifier(YulString _originalName)
{
if ((m_externallyUsedIdentifiers.count(_originalName)))
return _originalName;
diff --git a/libyul/optimiser/Disambiguator.h b/libyul/optimiser/Disambiguator.h
index 74a491ab..bfb65682 100644
--- a/libyul/optimiser/Disambiguator.h
+++ b/libyul/optimiser/Disambiguator.h
@@ -45,7 +45,7 @@ class Disambiguator: public ASTCopier
public:
explicit Disambiguator(
solidity::assembly::AsmAnalysisInfo const& _analysisInfo,
- std::set<std::string> const& _externallyUsedIdentifiers = {}
+ std::set<YulString> const& _externallyUsedIdentifiers = {}
):
m_info(_analysisInfo), m_externallyUsedIdentifiers(_externallyUsedIdentifiers), m_nameDispenser(m_externallyUsedIdentifiers)
{
@@ -56,16 +56,16 @@ protected:
virtual void leaveScope(Block const& _block) override;
virtual void enterFunction(FunctionDefinition const& _function) override;
virtual void leaveFunction(FunctionDefinition const& _function) override;
- virtual std::string translateIdentifier(std::string const& _name) override;
+ virtual YulString translateIdentifier(YulString _name) override;
void enterScopeInternal(solidity::assembly::Scope& _scope);
void leaveScopeInternal(solidity::assembly::Scope& _scope);
solidity::assembly::AsmAnalysisInfo const& m_info;
- std::set<std::string> const& m_externallyUsedIdentifiers;
+ std::set<YulString> const& m_externallyUsedIdentifiers;
std::vector<solidity::assembly::Scope*> m_scopes;
- std::map<void const*, std::string> m_translations;
+ std::map<void const*, YulString> m_translations;
NameDispenser m_nameDispenser;
};
diff --git a/libyul/optimiser/ExpressionInliner.cpp b/libyul/optimiser/ExpressionInliner.cpp
index 9bf0a3fb..07e88191 100644
--- a/libyul/optimiser/ExpressionInliner.cpp
+++ b/libyul/optimiser/ExpressionInliner.cpp
@@ -62,7 +62,7 @@ void ExpressionInliner::visit(Expression& _expression)
if (m_inlinableFunctions.count(funCall.functionName.name) && movable)
{
FunctionDefinition const& fun = *m_inlinableFunctions.at(funCall.functionName.name);
- map<string, Expression const*> substitutions;
+ map<YulString, Expression const*> substitutions;
for (size_t i = 0; i < fun.parameters.size(); ++i)
substitutions[fun.parameters[i].name] = &funCall.arguments[i];
_expression = Substitution(substitutions).translate(*boost::get<Assignment>(fun.body.statements.front()).value);
diff --git a/libyul/optimiser/ExpressionInliner.h b/libyul/optimiser/ExpressionInliner.h
index 971a2ee0..d903664f 100644
--- a/libyul/optimiser/ExpressionInliner.h
+++ b/libyul/optimiser/ExpressionInliner.h
@@ -59,10 +59,10 @@ public:
virtual void visit(Expression& _expression) override;
private:
- std::map<std::string, FunctionDefinition const*> m_inlinableFunctions;
- std::map<std::string, std::string> m_varReplacements;
+ std::map<YulString, FunctionDefinition const*> m_inlinableFunctions;
+ std::map<YulString, YulString> m_varReplacements;
/// Set of functions we are currently visiting inside.
- std::set<std::string> m_currentFunctions;
+ std::set<YulString> m_currentFunctions;
Block& m_block;
};
diff --git a/libyul/optimiser/ExpressionJoiner.h b/libyul/optimiser/ExpressionJoiner.h
index 4f06cc0f..0cc61981 100644
--- a/libyul/optimiser/ExpressionJoiner.h
+++ b/libyul/optimiser/ExpressionJoiner.h
@@ -93,9 +93,9 @@ private:
bool isLatestStatementVarDeclJoinable(Identifier const& _identifier);
private:
- Block* m_currentBlock = nullptr; ///< Pointer to currently block holding the visiting statement.
- size_t m_latestStatementInBlock = 0; ///< Offset to m_currentBlock's statements of the last visited statement.
- std::map<std::string, size_t> m_references; ///< Holds reference counts to all variable declarations in current block.
+ Block* m_currentBlock = nullptr; ///< Pointer to current block holding the statement being visited.
+ size_t m_latestStatementInBlock = 0; ///< Offset to m_currentBlock's statements of the last visited statement.
+ std::map<YulString, size_t> m_references; ///< Holds reference counts to all variable declarations in current block.
};
}
diff --git a/libyul/optimiser/ExpressionSimplifier.h b/libyul/optimiser/ExpressionSimplifier.h
index 5419ff6a..5965a1bb 100644
--- a/libyul/optimiser/ExpressionSimplifier.h
+++ b/libyul/optimiser/ExpressionSimplifier.h
@@ -44,11 +44,11 @@ public:
static void run(Block& _ast);
private:
- explicit ExpressionSimplifier(std::map<std::string, Expression const*> _ssaValues):
+ explicit ExpressionSimplifier(std::map<YulString, Expression const*> _ssaValues):
m_ssaValues(std::move(_ssaValues))
{}
- std::map<std::string, Expression const*> m_ssaValues;
+ std::map<YulString, Expression const*> m_ssaValues;
};
}
diff --git a/libyul/optimiser/ExpressionSplitter.cpp b/libyul/optimiser/ExpressionSplitter.cpp
index a2ecc546..a4b7a909 100644
--- a/libyul/optimiser/ExpressionSplitter.cpp
+++ b/libyul/optimiser/ExpressionSplitter.cpp
@@ -95,10 +95,10 @@ void ExpressionSplitter::outlineExpression(Expression& _expr)
visit(_expr);
SourceLocation location = locationOf(_expr);
- string var = m_nameDispenser.newName("");
+ YulString var = m_nameDispenser.newName({});
m_statementsToPrefix.emplace_back(VariableDeclaration{
location,
- {{TypedName{location, var, ""}}},
+ {{TypedName{location, var, {}}}},
make_shared<Expression>(std::move(_expr))
});
_expr = Identifier{location, var};
diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp
index 280d625a..c9057cf3 100644
--- a/libyul/optimiser/FullInliner.cpp
+++ b/libyul/optimiser/FullInliner.cpp
@@ -48,9 +48,9 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser):
tracker(m_ast);
for (auto const& ssaValue: tracker.values())
if (ssaValue.second && ssaValue.second->type() == typeid(Literal))
- m_constants.insert(ssaValue.first);
+ m_constants.emplace(ssaValue.first);
- map<string, size_t> references = ReferencesCounter::countReferences(m_ast);
+ map<YulString, size_t> references = ReferencesCounter::countReferences(m_ast);
for (auto& statement: m_ast.statements)
{
if (statement.type() != typeid(FunctionDefinition))
@@ -59,7 +59,7 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser):
m_functions[fun.name] = &fun;
// Always inline functions that are only called once.
if (references[fun.name] == 1)
- m_alwaysInline.insert(fun.name);
+ m_alwaysInline.emplace(fun.name);
updateCodeSize(fun);
}
}
@@ -68,7 +68,7 @@ void FullInliner::run()
{
for (auto& statement: m_ast.statements)
if (statement.type() == typeid(Block))
- handleBlock("", boost::get<Block>(statement));
+ handleBlock({}, boost::get<Block>(statement));
// TODO it might be good to determine a visiting order:
// first handle functions that are called from many places.
@@ -84,12 +84,12 @@ void FullInliner::updateCodeSize(FunctionDefinition& fun)
m_functionSizes[fun.name] = CodeSize::codeSize(fun.body);
}
-void FullInliner::handleBlock(string const& _currentFunctionName, Block& _block)
+void FullInliner::handleBlock(YulString _currentFunctionName, Block& _block)
{
InlineModifier{*this, m_nameDispenser, _currentFunctionName}(_block);
}
-bool FullInliner::shallInline(FunctionCall const& _funCall, string const& _callSite)
+bool FullInliner::shallInline(FunctionCall const& _funCall, YulString _callSite)
{
// No recursive inlining
if (_funCall.functionName.name == _callSite)
@@ -148,14 +148,14 @@ boost::optional<vector<Statement>> InlineModifier::tryInlineStatement(Statement&
vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionCall& _funCall)
{
vector<Statement> newStatements;
- map<string, string> variableReplacements;
+ map<YulString, YulString> variableReplacements;
FunctionDefinition& function = m_driver.function(_funCall.functionName.name);
// helper function to create a new variable that is supposed to model
// an existing variable.
auto newVariable = [&](TypedName const& _existingVariable, Expression* _value) {
- string newName = m_nameDispenser.newName(_existingVariable.name, function.name);
+ YulString newName = m_nameDispenser.newName(_existingVariable.name, function.name);
variableReplacements[_existingVariable.name] = newName;
VariableDeclaration varDecl{_funCall.location, {{_funCall.location, newName, _existingVariable.type}}, {}};
if (_value)
@@ -214,7 +214,7 @@ Statement BodyCopier::operator()(FunctionDefinition const& _funDef)
return _funDef;
}
-string BodyCopier::translateIdentifier(string const& _name)
+YulString BodyCopier::translateIdentifier(YulString _name)
{
if (m_variableReplacements.count(_name))
return m_variableReplacements.at(_name);
diff --git a/libyul/optimiser/FullInliner.h b/libyul/optimiser/FullInliner.h
index 5ecfb57a..66ce8e2f 100644
--- a/libyul/optimiser/FullInliner.h
+++ b/libyul/optimiser/FullInliner.h
@@ -77,23 +77,23 @@ public:
/// Inlining heuristic.
/// @param _callSite the name of the function in which the function call is located.
- bool shallInline(FunctionCall const& _funCall, std::string const& _callSite);
+ bool shallInline(FunctionCall const& _funCall, YulString _callSite);
- FunctionDefinition& function(std::string _name) { return *m_functions.at(_name); }
+ FunctionDefinition& function(YulString _name) { return *m_functions.at(_name); }
private:
void updateCodeSize(FunctionDefinition& fun);
- void handleBlock(std::string const& _currentFunctionName, Block& _block);
+ void handleBlock(YulString _currentFunctionName, Block& _block);
/// The AST to be modified. The root block itself will not be modified, because
/// we store pointers to functions.
Block& m_ast;
- std::map<std::string, FunctionDefinition*> m_functions;
+ std::map<YulString, FunctionDefinition*> m_functions;
/// Names of functions to always inline.
- std::set<std::string> m_alwaysInline;
+ std::set<YulString> m_alwaysInline;
/// Variables that are constants (used for inlining heuristic)
- std::set<std::string> m_constants;
- std::map<std::string, size_t> m_functionSizes;
+ std::set<YulString> m_constants;
+ std::map<YulString, size_t> m_functionSizes;
NameDispenser& m_nameDispenser;
};
@@ -104,7 +104,7 @@ private:
class InlineModifier: public ASTModifier
{
public:
- InlineModifier(FullInliner& _driver, NameDispenser& _nameDispenser, std::string _functionName):
+ InlineModifier(FullInliner& _driver, NameDispenser& _nameDispenser, YulString _functionName):
m_currentFunction(std::move(_functionName)),
m_driver(_driver),
m_nameDispenser(_nameDispenser)
@@ -116,7 +116,7 @@ private:
boost::optional<std::vector<Statement>> tryInlineStatement(Statement& _statement);
std::vector<Statement> performInline(Statement& _statement, FunctionCall& _funCall);
- std::string m_currentFunction;
+ YulString m_currentFunction;
FullInliner& m_driver;
NameDispenser& m_nameDispenser;
};
@@ -131,8 +131,8 @@ class BodyCopier: public ASTCopier
public:
BodyCopier(
NameDispenser& _nameDispenser,
- std::string const& _varNamePrefix,
- std::map<std::string, std::string> const& _variableReplacements
+ YulString _varNamePrefix,
+ std::map<YulString, YulString> const& _variableReplacements
):
m_nameDispenser(_nameDispenser),
m_varNamePrefix(_varNamePrefix),
@@ -144,11 +144,11 @@ public:
virtual Statement operator()(VariableDeclaration const& _varDecl) override;
virtual Statement operator()(FunctionDefinition const& _funDef) override;
- virtual std::string translateIdentifier(std::string const& _name) override;
+ virtual YulString translateIdentifier(YulString _name) override;
NameDispenser& m_nameDispenser;
- std::string const& m_varNamePrefix;
- std::map<std::string, std::string> m_variableReplacements;
+ YulString m_varNamePrefix;
+ std::map<YulString, YulString> m_variableReplacements;
};
diff --git a/libyul/optimiser/InlinableExpressionFunctionFinder.cpp b/libyul/optimiser/InlinableExpressionFunctionFinder.cpp
index 69dd2095..deaaee97 100644
--- a/libyul/optimiser/InlinableExpressionFunctionFinder.cpp
+++ b/libyul/optimiser/InlinableExpressionFunctionFinder.cpp
@@ -44,7 +44,7 @@ void InlinableExpressionFunctionFinder::operator()(FunctionDefinition const& _fu
{
if (_function.returnVariables.size() == 1 && _function.body.statements.size() == 1)
{
- string const& retVariable = _function.returnVariables.front().name;
+ YulString retVariable = _function.returnVariables.front().name;
Statement const& bodyStatement = _function.body.statements.front();
if (bodyStatement.type() == typeid(Assignment))
{
@@ -57,7 +57,7 @@ void InlinableExpressionFunctionFinder::operator()(FunctionDefinition const& _fu
// would not be valid here if we were searching inside a functionally inlinable
// function body.
assertThrow(m_disallowedIdentifiers.empty() && !m_foundDisallowedIdentifier, OptimizerException, "");
- m_disallowedIdentifiers = set<string>{retVariable, _function.name};
+ m_disallowedIdentifiers = set<YulString>{retVariable, _function.name};
boost::apply_visitor(*this, *assignment.value);
if (!m_foundDisallowedIdentifier)
m_inlinableFunctions[_function.name] = &_function;
diff --git a/libyul/optimiser/InlinableExpressionFunctionFinder.h b/libyul/optimiser/InlinableExpressionFunctionFinder.h
index 3887e6e5..baf4bbfc 100644
--- a/libyul/optimiser/InlinableExpressionFunctionFinder.h
+++ b/libyul/optimiser/InlinableExpressionFunctionFinder.h
@@ -43,7 +43,7 @@ class InlinableExpressionFunctionFinder: public ASTWalker
{
public:
- std::map<std::string, FunctionDefinition const*> const& inlinableFunctions() const
+ std::map<YulString, FunctionDefinition const*> const& inlinableFunctions() const
{
return m_inlinableFunctions;
}
@@ -54,15 +54,15 @@ public:
virtual void operator()(FunctionDefinition const& _function) override;
private:
- void checkAllowed(std::string const& _name)
+ void checkAllowed(YulString _name)
{
if (m_disallowedIdentifiers.count(_name))
m_foundDisallowedIdentifier = true;
}
bool m_foundDisallowedIdentifier = false;
- std::set<std::string> m_disallowedIdentifiers;
- std::map<std::string, FunctionDefinition const*> m_inlinableFunctions;
+ std::set<YulString> m_disallowedIdentifiers;
+ std::map<YulString, FunctionDefinition const*> m_inlinableFunctions;
};
}
diff --git a/libyul/optimiser/MainFunction.cpp b/libyul/optimiser/MainFunction.cpp
index c8f35207..f3306598 100644
--- a/libyul/optimiser/MainFunction.cpp
+++ b/libyul/optimiser/MainFunction.cpp
@@ -40,12 +40,12 @@ void MainFunction::operator()(Block& _block)
for (size_t i = 1; i < _block.statements.size(); ++i)
assertThrow(_block.statements.at(i).type() == typeid(FunctionDefinition), OptimizerException, "");
/// @todo this should handle scopes properly and instead of an assertion it should rename the conflicting function
- assertThrow(NameCollector(_block).names().count("main") == 0, OptimizerException, "");
+ assertThrow(NameCollector(_block).names().count(YulString{"main"}) == 0, OptimizerException, "");
Block& block = boost::get<Block>(_block.statements[0]);
FunctionDefinition main{
block.location,
- "main",
+ YulString{"main"},
{},
{},
std::move(block)
diff --git a/libyul/optimiser/NameCollector.cpp b/libyul/optimiser/NameCollector.cpp
index b71fa982..36f55b99 100644
--- a/libyul/optimiser/NameCollector.cpp
+++ b/libyul/optimiser/NameCollector.cpp
@@ -29,16 +29,16 @@ using namespace dev::yul;
void NameCollector::operator()(VariableDeclaration const& _varDecl)
{
for (auto const& var: _varDecl.variables)
- m_names.insert(var.name);
+ m_names.emplace(var.name);
}
void NameCollector::operator ()(FunctionDefinition const& _funDef)
{
- m_names.insert(_funDef.name);
+ m_names.emplace(_funDef.name);
for (auto const arg: _funDef.parameters)
- m_names.insert(arg.name);
+ m_names.emplace(arg.name);
for (auto const ret: _funDef.returnVariables)
- m_names.insert(ret.name);
+ m_names.emplace(ret.name);
ASTWalker::operator ()(_funDef);
}
@@ -53,14 +53,14 @@ void ReferencesCounter::operator()(FunctionCall const& _funCall)
ASTWalker::operator()(_funCall);
}
-map<string, size_t> ReferencesCounter::countReferences(Block const& _block)
+map<YulString, size_t> ReferencesCounter::countReferences(Block const& _block)
{
ReferencesCounter counter;
counter(_block);
return counter.references();
}
-map<string, size_t> ReferencesCounter::countReferences(Expression const& _expression)
+map<YulString, size_t> ReferencesCounter::countReferences(Expression const& _expression)
{
ReferencesCounter counter;
counter.visit(_expression);
@@ -70,5 +70,5 @@ map<string, size_t> ReferencesCounter::countReferences(Expression const& _expres
void Assignments::operator()(Assignment const& _assignment)
{
for (auto const& var: _assignment.variableNames)
- m_names.insert(var.name);
+ m_names.emplace(var.name);
}
diff --git a/libyul/optimiser/NameCollector.h b/libyul/optimiser/NameCollector.h
index b8f6c1d7..b76eec30 100644
--- a/libyul/optimiser/NameCollector.h
+++ b/libyul/optimiser/NameCollector.h
@@ -22,7 +22,6 @@
#include <libyul/optimiser/ASTWalker.h>
-#include <string>
#include <map>
#include <set>
@@ -46,9 +45,9 @@ public:
virtual void operator()(VariableDeclaration const& _varDecl) override;
virtual void operator()(FunctionDefinition const& _funDef) override;
- std::set<std::string> names() const { return m_names; }
+ std::set<YulString> names() const { return m_names; }
private:
- std::set<std::string> m_names;
+ std::set<YulString> m_names;
};
/**
@@ -61,12 +60,12 @@ public:
virtual void operator()(Identifier const& _identifier);
virtual void operator()(FunctionCall const& _funCall);
- static std::map<std::string, size_t> countReferences(Block const& _block);
- static std::map<std::string, size_t> countReferences(Expression const& _expression);
+ static std::map<YulString, size_t> countReferences(Block const& _block);
+ static std::map<YulString, size_t> countReferences(Expression const& _expression);
- std::map<std::string, size_t> const& references() const { return m_references; }
+ std::map<YulString, size_t> const& references() const { return m_references; }
private:
- std::map<std::string, size_t> m_references;
+ std::map<YulString, size_t> m_references;
};
/**
@@ -78,9 +77,9 @@ public:
using ASTWalker::operator ();
virtual void operator()(Assignment const& _assignment) override;
- std::set<std::string> const& names() const { return m_names; }
+ std::set<YulString> const& names() const { return m_names; }
private:
- std::set<std::string> m_names;
+ std::set<YulString> m_names;
};
}
diff --git a/libyul/optimiser/NameDispenser.cpp b/libyul/optimiser/NameDispenser.cpp
index d3f10bc2..492c863d 100644
--- a/libyul/optimiser/NameDispenser.cpp
+++ b/libyul/optimiser/NameDispenser.cpp
@@ -33,31 +33,31 @@ NameDispenser::NameDispenser(Block const& _ast):
{
}
-NameDispenser::NameDispenser(set<string> _usedNames):
+NameDispenser::NameDispenser(set<YulString> _usedNames):
m_usedNames(std::move(_usedNames))
{
}
-string NameDispenser::newName(string const& _nameHint, string const& _context)
+YulString NameDispenser::newName(YulString _nameHint, YulString _context)
{
// Shortening rules: Use a suffix of _prefix and a prefix of _context.
- string prefix = _nameHint;
+ YulString prefix = _nameHint;
if (!_context.empty())
- prefix = _context.substr(0, 10) + "_" + prefix;
+ prefix = YulString{_context.str().substr(0, 10) + "_" + prefix.str()};
return newNameInternal(prefix);
}
-string NameDispenser::newNameInternal(string const& _nameHint)
+YulString NameDispenser::newNameInternal(YulString _nameHint)
{
+ YulString name = _nameHint;
size_t suffix = 0;
- string name = _nameHint;
while (name.empty() || m_usedNames.count(name))
{
suffix++;
- name = _nameHint + "_" + to_string(suffix);
+ name = YulString(_nameHint.str() + "_" + to_string(suffix));
}
- m_usedNames.insert(name);
+ m_usedNames.emplace(name);
return name;
}
diff --git a/libyul/optimiser/NameDispenser.h b/libyul/optimiser/NameDispenser.h
index 5fbf5f8e..57adbcad 100644
--- a/libyul/optimiser/NameDispenser.h
+++ b/libyul/optimiser/NameDispenser.h
@@ -21,8 +21,9 @@
#include <libyul/ASTDataForward.h>
+#include <libyul/YulString.h>
+
#include <set>
-#include <string>
namespace dev
{
@@ -41,18 +42,18 @@ public:
/// Initialize the name dispenser with all the names used in the given AST.
explicit NameDispenser(Block const& _ast);
/// Initialize the name dispenser with the given used names.
- explicit NameDispenser(std::set<std::string> _usedNames);
+ explicit NameDispenser(std::set<YulString> _usedNames);
/// @returns a currently unused name that should be similar to _nameHint
/// and prefixed by _context if present.
/// If the resulting name would be too long, trims the context at the end
/// and the name hint at the start.
- std::string newName(std::string const& _nameHint, std::string const& _context = {});
+ YulString newName(YulString _nameHint, YulString _context = {});
private:
- std::string newNameInternal(std::string const& _nameHint);
+ YulString newNameInternal(YulString _nameHint);
- std::set<std::string> m_usedNames;
+ std::set<YulString> m_usedNames;
};
}
diff --git a/libyul/optimiser/RedundantAssignEliminator.cpp b/libyul/optimiser/RedundantAssignEliminator.cpp
index 478858e4..775b7673 100644
--- a/libyul/optimiser/RedundantAssignEliminator.cpp
+++ b/libyul/optimiser/RedundantAssignEliminator.cpp
@@ -44,7 +44,7 @@ void RedundantAssignEliminator::operator()(VariableDeclaration const& _variableD
ASTWalker::operator()(_variableDeclaration);
for (auto const& var: _variableDeclaration.variables)
- m_declaredVariables.insert(var.name);
+ m_declaredVariables.emplace(var.name);
}
void RedundantAssignEliminator::operator()(Assignment const& _assignment)
@@ -156,7 +156,7 @@ void RedundantAssignEliminator::run(Block& _ast)
{
assertThrow(assignment.second != State::Undecided, OptimizerException, "");
if (assignment.second == State::Unused && MovableChecker{*assignment.first->value}.movable())
- assignmentsToRemove.insert(assignment.first);
+ assignmentsToRemove.emplace(assignment.first);
}
AssignmentRemover remover{assignmentsToRemove};
@@ -176,7 +176,7 @@ void RedundantAssignEliminator::join(RedundantAssignEliminator& _other)
m_assignments[var.first] = std::move(var.second);
}
-void RedundantAssignEliminator::changeUndecidedTo(string const& _variable, RedundantAssignEliminator::State _newState)
+void RedundantAssignEliminator::changeUndecidedTo(YulString _variable, RedundantAssignEliminator::State _newState)
{
for (auto& assignment: m_assignments[_variable])
if (assignment.second == State{State::Undecided})
diff --git a/libyul/optimiser/RedundantAssignEliminator.h b/libyul/optimiser/RedundantAssignEliminator.h
index 52092138..805a1f63 100644
--- a/libyul/optimiser/RedundantAssignEliminator.h
+++ b/libyul/optimiser/RedundantAssignEliminator.h
@@ -125,9 +125,9 @@ private:
public:
enum Value { Unused, Undecided, Used };
State(Value _value = Undecided): m_value(_value) {}
- bool operator==(State _other) const { return m_value == _other.m_value; }
- bool operator!=(State _other) const { return !operator==(_other); }
- void join(State _other)
+ inline bool operator==(State _other) const { return m_value == _other.m_value; }
+ inline bool operator!=(State _other) const { return !operator==(_other); }
+ inline void join(State const& _other)
{
// Using "max" works here because of the order of the values in the enum.
m_value = Value(std::max(int(_other.m_value), int(m_value)));
@@ -156,17 +156,18 @@ private:
private:
RedundantAssignEliminator& m_rae;
- std::set<std::string> m_outerDeclaredVariables;
+ std::set<YulString> m_outerDeclaredVariables;
};
/// Joins the assignment mapping with @a _other according to the rules laid out
/// above.
/// Will destroy @a _other.
void join(RedundantAssignEliminator& _other);
- void changeUndecidedTo(std::string const& _variable, State _newState);
+ void changeUndecidedTo(YulString _variable, State _newState);
- std::set<std::string> m_declaredVariables;
- std::map<std::string, std::map<Assignment const*, State>> m_assignments;
+ std::set<YulString> m_declaredVariables;
+ // TODO check that this does not cause nondeterminism!
+ std::map<YulString, std::map<Assignment const*, State>> m_assignments;
};
class AssignmentRemover: public ASTModifier
diff --git a/libyul/optimiser/Rematerialiser.cpp b/libyul/optimiser/Rematerialiser.cpp
index a99db0b6..38d50ef4 100644
--- a/libyul/optimiser/Rematerialiser.cpp
+++ b/libyul/optimiser/Rematerialiser.cpp
@@ -37,7 +37,7 @@ void Rematerialiser::visit(Expression& _e)
Identifier& identifier = boost::get<Identifier>(_e);
if (m_value.count(identifier.name))
{
- string name = identifier.name;
+ YulString name = identifier.name;
for (auto const& ref: m_references[name])
assertThrow(inScope(ref), OptimizerException, "");
assertThrow(m_value.at(name), OptimizerException, "");
diff --git a/libyul/optimiser/Rematerialiser.h b/libyul/optimiser/Rematerialiser.h
index afcfab3e..f82465eb 100644
--- a/libyul/optimiser/Rematerialiser.h
+++ b/libyul/optimiser/Rematerialiser.h
@@ -22,10 +22,6 @@
#include <libyul/optimiser/DataFlowAnalyzer.h>
-#include <string>
-#include <map>
-#include <set>
-
namespace dev
{
namespace yul
diff --git a/libyul/optimiser/SSATransform.cpp b/libyul/optimiser/SSATransform.cpp
index 9db7bd03..f209ee7b 100644
--- a/libyul/optimiser/SSATransform.cpp
+++ b/libyul/optimiser/SSATransform.cpp
@@ -62,15 +62,15 @@ void SSATransform::operator()(ForLoop& _for)
void SSATransform::operator()(Block& _block)
{
- set<string> variablesToClearAtEnd;
+ set<YulString> variablesToClearAtEnd;
// Creates a new variable (and returns its declaration) with value _value
// and replaces _value by a reference to that new variable.
- auto replaceByNew = [&](SourceLocation _loc, string _varName, string _type, shared_ptr<Expression>& _value) -> VariableDeclaration
+ auto replaceByNew = [&](SourceLocation _loc, YulString _varName, YulString _type, shared_ptr<Expression>& _value) -> VariableDeclaration
{
- string newName = m_nameDispenser.newName(_varName);
+ YulString newName = m_nameDispenser.newName(_varName);
m_currentVariableValues[_varName] = newName;
- variablesToClearAtEnd.insert(_varName);
+ variablesToClearAtEnd.emplace(_varName);
shared_ptr<Expression> v = make_shared<Expression>(Identifier{_loc, newName});
_value.swap(v);
return VariableDeclaration{_loc, {TypedName{_loc, std::move(newName), std::move(_type)}}, std::move(v)};
diff --git a/libyul/optimiser/SSATransform.h b/libyul/optimiser/SSATransform.h
index 2adc657d..bb642549 100644
--- a/libyul/optimiser/SSATransform.h
+++ b/libyul/optimiser/SSATransform.h
@@ -85,13 +85,13 @@ public:
static void run(Block& _ast, NameDispenser& _nameDispenser);
private:
- explicit SSATransform(NameDispenser& _nameDispenser, std::set<std::string> const& _variablesToReplace):
+ explicit SSATransform(NameDispenser& _nameDispenser, std::set<YulString> const& _variablesToReplace):
m_nameDispenser(_nameDispenser), m_variablesToReplace(_variablesToReplace)
{ }
NameDispenser& m_nameDispenser;
- std::set<std::string> const& m_variablesToReplace;
- std::map<std::string, std::string> m_currentVariableValues;
+ std::set<YulString> const& m_variablesToReplace;
+ std::map<YulString, YulString> m_currentVariableValues;
};
}
diff --git a/libyul/optimiser/SSAValueTracker.cpp b/libyul/optimiser/SSAValueTracker.cpp
index a1291d67..491117da 100644
--- a/libyul/optimiser/SSAValueTracker.cpp
+++ b/libyul/optimiser/SSAValueTracker.cpp
@@ -42,7 +42,7 @@ void SSAValueTracker::operator()(VariableDeclaration const& _varDecl)
setValue(var.name, nullptr);
}
-void SSAValueTracker::setValue(string const& _name, Expression const* _value)
+void SSAValueTracker::setValue(YulString _name, Expression const* _value)
{
assertThrow(
m_values.count(_name) == 0,
diff --git a/libyul/optimiser/SSAValueTracker.h b/libyul/optimiser/SSAValueTracker.h
index 8c39a98e..d1539c86 100644
--- a/libyul/optimiser/SSAValueTracker.h
+++ b/libyul/optimiser/SSAValueTracker.h
@@ -23,7 +23,6 @@
#include <libyul/optimiser/ASTWalker.h>
-#include <string>
#include <map>
#include <set>
@@ -45,13 +44,13 @@ public:
virtual void operator()(VariableDeclaration const& _varDecl) override;
virtual void operator()(Assignment const& _assignment) override;
- std::map<std::string, Expression const*> const& values() const { return m_values; }
- Expression const* value(std::string const& _name) const { return m_values.at(_name); }
+ std::map<YulString, Expression const*> const& values() const { return m_values; }
+ Expression const* value(YulString _name) const { return m_values.at(_name); }
private:
- void setValue(std::string const& _name, Expression const* _value);
+ void setValue(YulString _name, Expression const* _value);
- std::map<std::string, Expression const*> m_values;
+ std::map<YulString, Expression const*> m_values;
};
}
diff --git a/libyul/optimiser/Semantics.cpp b/libyul/optimiser/Semantics.cpp
index 33f3af77..3c49016e 100644
--- a/libyul/optimiser/Semantics.cpp
+++ b/libyul/optimiser/Semantics.cpp
@@ -40,7 +40,7 @@ MovableChecker::MovableChecker(Expression const& _expression)
void MovableChecker::operator()(Identifier const& _identifier)
{
ASTWalker::operator()(_identifier);
- m_variableReferences.insert(_identifier.name);
+ m_variableReferences.emplace(_identifier.name);
}
void MovableChecker::operator()(FunctionalInstruction const& _instr)
diff --git a/libyul/optimiser/Semantics.h b/libyul/optimiser/Semantics.h
index 1caa12fb..620a91cb 100644
--- a/libyul/optimiser/Semantics.h
+++ b/libyul/optimiser/Semantics.h
@@ -22,8 +22,6 @@
#include <libyul/optimiser/ASTWalker.h>
-#include <string>
-#include <map>
#include <set>
namespace dev
@@ -49,11 +47,11 @@ public:
using ASTWalker::visit;
bool movable() const { return m_movable; }
- std::set<std::string> const& referencedVariables() const { return m_variableReferences; }
+ std::set<YulString> const& referencedVariables() const { return m_variableReferences; }
private:
/// Which variables the current expression references.
- std::set<std::string> m_variableReferences;
+ std::set<YulString> m_variableReferences;
/// Is the current expression movable or not.
bool m_movable = true;
};
diff --git a/libyul/optimiser/SimplificationRules.cpp b/libyul/optimiser/SimplificationRules.cpp
index aca943b0..5721042f 100644
--- a/libyul/optimiser/SimplificationRules.cpp
+++ b/libyul/optimiser/SimplificationRules.cpp
@@ -36,7 +36,7 @@ using namespace dev::yul;
SimplificationRule<Pattern> const* SimplificationRules::findFirstMatch(
Expression const& _expr,
- map<string, Expression const*> const& _ssaValues
+ map<YulString, Expression const*> const& _ssaValues
)
{
if (_expr.type() != typeid(FunctionalInstruction))
@@ -46,7 +46,7 @@ SimplificationRule<Pattern> const* SimplificationRules::findFirstMatch(
assertThrow(rules.isInitialized(), OptimizerException, "Rule list not properly initialized.");
FunctionalInstruction const& instruction = boost::get<FunctionalInstruction>(_expr);
- for (auto const& rule: rules.m_rules[byte(instruction.instruction)])
+ for (auto const& rule: rules.m_rules[uint8_t(instruction.instruction)])
{
rules.resetMatchGroups();
if (rule.pattern.matches(_expr, _ssaValues))
@@ -57,7 +57,7 @@ SimplificationRule<Pattern> const* SimplificationRules::findFirstMatch(
bool SimplificationRules::isInitialized() const
{
- return !m_rules[byte(solidity::Instruction::ADD)].empty();
+ return !m_rules[uint8_t(solidity::Instruction::ADD)].empty();
}
void SimplificationRules::addRules(vector<SimplificationRule<Pattern>> const& _rules)
@@ -68,7 +68,7 @@ void SimplificationRules::addRules(vector<SimplificationRule<Pattern>> const& _r
void SimplificationRules::addRule(SimplificationRule<Pattern> const& _rule)
{
- m_rules[byte(_rule.pattern.instruction())].push_back(_rule);
+ m_rules[uint8_t(_rule.pattern.instruction())].push_back(_rule);
}
SimplificationRules::SimplificationRules()
@@ -104,7 +104,7 @@ void Pattern::setMatchGroup(unsigned _group, map<unsigned, Expression const*>& _
m_matchGroups = &_matchGroups;
}
-bool Pattern::matches(Expression const& _expr, map<string, Expression const*> const& _ssaValues) const
+bool Pattern::matches(Expression const& _expr, map<YulString, Expression const*> const& _ssaValues) const
{
Expression const* expr = &_expr;
@@ -112,7 +112,7 @@ bool Pattern::matches(Expression const& _expr, map<string, Expression const*> co
// Do not do it for "Any" because we can check identity better for variables.
if (m_kind != PatternKind::Any && _expr.type() == typeid(Identifier))
{
- string const& varName = boost::get<Identifier>(_expr).name;
+ YulString varName = boost::get<Identifier>(_expr).name;
if (_ssaValues.count(varName))
expr = _ssaValues.at(varName);
}
@@ -125,7 +125,7 @@ bool Pattern::matches(Expression const& _expr, map<string, Expression const*> co
Literal const& literal = boost::get<Literal>(*expr);
if (literal.kind != assembly::LiteralKind::Number)
return false;
- if (m_data && *m_data != u256(literal.value))
+ if (m_data && *m_data != u256(literal.value.str()))
return false;
assertThrow(m_arguments.empty(), OptimizerException, "");
}
@@ -193,7 +193,7 @@ Expression Pattern::toExpression(SourceLocation const& _location) const
if (m_kind == PatternKind::Constant)
{
assertThrow(m_data, OptimizerException, "No match group and no constant value given.");
- return Literal{_location, assembly::LiteralKind::Number, formatNumber(*m_data), ""};
+ return Literal{_location, assembly::LiteralKind::Number, YulString{formatNumber(*m_data)}, {}};
}
else if (m_kind == PatternKind::Operation)
{
@@ -209,8 +209,8 @@ u256 Pattern::d() const
{
Literal const& literal = boost::get<Literal>(matchGroupValue());
assertThrow(literal.kind == assembly::LiteralKind::Number, OptimizerException, "");
- assertThrow(isValidDecimal(literal.value) || isValidHex(literal.value), OptimizerException, "");
- return u256(literal.value);
+ assertThrow(isValidDecimal(literal.value.str()) || isValidHex(literal.value.str()), OptimizerException, "");
+ return u256(literal.value.str());
}
Expression const& Pattern::matchGroupValue() const
diff --git a/libyul/optimiser/SimplificationRules.h b/libyul/optimiser/SimplificationRules.h
index 82ae5d22..b608ca91 100644
--- a/libyul/optimiser/SimplificationRules.h
+++ b/libyul/optimiser/SimplificationRules.h
@@ -52,7 +52,7 @@ public:
/// @param _ssaValues values of variables that are assigned exactly once.
static SimplificationRule<Pattern> const* findFirstMatch(
Expression const& _expr,
- std::map<std::string, Expression const*> const& _ssaValues
+ std::map<YulString, Expression const*> const& _ssaValues
);
/// Checks whether the rulelist is non-empty. This is usually enforced
@@ -96,7 +96,7 @@ public:
/// same expression equivalence class.
void setMatchGroup(unsigned _group, std::map<unsigned, Expression const*>& _matchGroups);
unsigned matchGroup() const { return m_matchGroup; }
- bool matches(Expression const& _expr, std::map<std::string, Expression const*> const& _ssaValues) const;
+ bool matches(Expression const& _expr, std::map<YulString, Expression const*> const& _ssaValues) const;
std::vector<Pattern> arguments() const { return m_arguments; }
diff --git a/libyul/optimiser/Substitution.cpp b/libyul/optimiser/Substitution.cpp
index 4a000a85..9b3d4c03 100644
--- a/libyul/optimiser/Substitution.cpp
+++ b/libyul/optimiser/Substitution.cpp
@@ -30,7 +30,7 @@ Expression Substitution::translate(Expression const& _expression)
{
if (_expression.type() == typeid(Identifier))
{
- string const& name = boost::get<Identifier>(_expression).name;
+ YulString name = boost::get<Identifier>(_expression).name;
if (m_substitutions.count(name))
// No recursive substitution
return ASTCopier().translate(*m_substitutions.at(name));
diff --git a/libyul/optimiser/Substitution.h b/libyul/optimiser/Substitution.h
index b734cdca..59ee4620 100644
--- a/libyul/optimiser/Substitution.h
+++ b/libyul/optimiser/Substitution.h
@@ -22,9 +22,9 @@
#include <libyul/optimiser/ASTCopier.h>
-#include <string>
+#include <libyul/YulString.h>
+
#include <map>
-#include <set>
namespace dev
{
@@ -37,13 +37,13 @@ namespace yul
class Substitution: public ASTCopier
{
public:
- Substitution(std::map<std::string, Expression const*> const& _substitutions):
+ Substitution(std::map<YulString, Expression const*> const& _substitutions):
m_substitutions(_substitutions)
{}
virtual Expression translate(Expression const& _expression) override;
private:
- std::map<std::string, Expression const*> const& m_substitutions;
+ std::map<YulString, Expression const*> const& m_substitutions;
};
}
diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp
index 5b325afd..c7339d2e 100644
--- a/libyul/optimiser/Suite.cpp
+++ b/libyul/optimiser/Suite.cpp
@@ -48,10 +48,10 @@ using namespace dev::yul;
void OptimiserSuite::run(
Block& _ast,
solidity::assembly::AsmAnalysisInfo const& _analysisInfo,
- set<string> const& _externallyUsedIdentifiers
+ set<YulString> const& _externallyUsedIdentifiers
)
{
- set<string> reservedIdentifiers = _externallyUsedIdentifiers;
+ set<YulString> reservedIdentifiers = _externallyUsedIdentifiers;
Block ast = boost::get<Block>(Disambiguator(_analysisInfo, reservedIdentifiers)(_ast));
diff --git a/libyul/optimiser/Suite.h b/libyul/optimiser/Suite.h
index bb6274bd..5b564c56 100644
--- a/libyul/optimiser/Suite.h
+++ b/libyul/optimiser/Suite.h
@@ -21,9 +21,8 @@
#pragma once
#include <libyul/ASTDataForward.h>
+#include <libyul/YulString.h>
-#include <string>
-#include <map>
#include <set>
namespace dev
@@ -47,7 +46,8 @@ public:
static void run(
Block& _ast,
solidity::assembly::AsmAnalysisInfo const& _analysisInfo,
- std::set<std::string> const& _externallyUsedIdentifiers = std::set<std::string>()
+
+ std::set<YulString> const& _externallyUsedIdentifiers = {}
);
};
diff --git a/libyul/optimiser/SyntacticalEquality.cpp b/libyul/optimiser/SyntacticalEquality.cpp
index f22b5c31..66912383 100644
--- a/libyul/optimiser/SyntacticalEquality.cpp
+++ b/libyul/optimiser/SyntacticalEquality.cpp
@@ -34,6 +34,7 @@ bool SyntacticalEqualityChecker::equal(Expression const& _e1, Expression const&
{
if (_e1.type() != _e2.type())
return false;
+ // TODO This somehow calls strcmp - WHERE?
// TODO This should be replaced by some kind of AST walker as soon as it gets
// more complex.
diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp
index 37a74553..a7b32873 100644
--- a/libyul/optimiser/UnusedPruner.cpp
+++ b/libyul/optimiser/UnusedPruner.cpp
@@ -33,7 +33,7 @@ using namespace std;
using namespace dev;
using namespace dev::yul;
-UnusedPruner::UnusedPruner(Block& _ast, set<string> const& _externallyUsedFunctions)
+UnusedPruner::UnusedPruner(Block& _ast, set<YulString> const& _externallyUsedFunctions)
{
ReferencesCounter counter;
counter(_ast);
@@ -91,7 +91,7 @@ void UnusedPruner::operator()(Block& _block)
ASTModifier::operator()(_block);
}
-void UnusedPruner::runUntilStabilised(Block& _ast, set<string> const& _externallyUsedFunctions)
+void UnusedPruner::runUntilStabilised(Block& _ast, set<YulString> const& _externallyUsedFunctions)
{
while (true)
{
@@ -102,12 +102,12 @@ void UnusedPruner::runUntilStabilised(Block& _ast, set<string> const& _externall
}
}
-bool UnusedPruner::used(string const& _name) const
+bool UnusedPruner::used(YulString _name) const
{
return m_references.count(_name) && m_references.at(_name) > 0;
}
-void UnusedPruner::subtractReferences(map<string, size_t> const& _subtrahend)
+void UnusedPruner::subtractReferences(map<YulString, size_t> const& _subtrahend)
{
for (auto const& ref: _subtrahend)
{
diff --git a/libyul/optimiser/UnusedPruner.h b/libyul/optimiser/UnusedPruner.h
index 30617ff3..2dd74940 100644
--- a/libyul/optimiser/UnusedPruner.h
+++ b/libyul/optimiser/UnusedPruner.h
@@ -21,8 +21,8 @@
#pragma once
#include <libyul/optimiser/ASTWalker.h>
+#include <libyul/YulString.h>
-#include <string>
#include <map>
#include <set>
@@ -44,7 +44,7 @@ namespace yul
class UnusedPruner: public ASTModifier
{
public:
- explicit UnusedPruner(Block& _ast, std::set<std::string> const& _externallyUsedFunctions = std::set<std::string>());
+ explicit UnusedPruner(Block& _ast, std::set<YulString> const& _externallyUsedFunctions = {});
using ASTModifier::operator();
virtual void operator()(Block& _block) override;
@@ -53,14 +53,14 @@ public:
bool shouldRunAgain() const { return m_shouldRunAgain; }
// Run the pruner until the code does not change anymore.
- static void runUntilStabilised(Block& _ast, std::set<std::string> const& _externallyUsedFunctions = std::set<std::string>());
+ static void runUntilStabilised(Block& _ast, std::set<YulString> const& _externallyUsedFunctions = {});
private:
- bool used(std::string const& _name) const;
- void subtractReferences(std::map<std::string, size_t> const& _subtrahend);
+ bool used(YulString _name) const;
+ void subtractReferences(std::map<YulString, size_t> const& _subtrahend);
bool m_shouldRunAgain = false;
- std::map<std::string, size_t> m_references;
+ std::map<YulString, size_t> m_references;
};
}
diff --git a/libyul/optimiser/VarDeclPropagator.cpp b/libyul/optimiser/VarDeclPropagator.cpp
index 39337b3d..537b7020 100644
--- a/libyul/optimiser/VarDeclPropagator.cpp
+++ b/libyul/optimiser/VarDeclPropagator.cpp
@@ -31,8 +31,8 @@ using dev::solidity::assembly::TypedNameList;
void VarDeclPropagator::operator()(Block& _block)
{
- map<string, TypedName> outerEmptyVarDecls;
- map<string, TypedName> outerLazyInitializedVarDecls;
+ map<YulString, TypedName> outerEmptyVarDecls;
+ map<YulString, TypedName> outerLazyInitializedVarDecls;
swap(m_emptyVarDecls, outerEmptyVarDecls);
swap(m_lazyInitializedVarDecls, outerLazyInitializedVarDecls);
diff --git a/libyul/optimiser/VarDeclPropagator.h b/libyul/optimiser/VarDeclPropagator.h
index 8cba8649..4522d23a 100644
--- a/libyul/optimiser/VarDeclPropagator.h
+++ b/libyul/optimiser/VarDeclPropagator.h
@@ -53,10 +53,10 @@ private:
private:
/// Holds a list of variables from current Block that have no value assigned yet.
- std::map<std::string, TypedName> m_emptyVarDecls;
+ std::map<YulString, TypedName> m_emptyVarDecls;
/// Holds a list variables (and their TypedName) within the current block.
- std::map<std::string, TypedName> m_lazyInitializedVarDecls;
+ std::map<YulString, TypedName> m_lazyInitializedVarDecls;
};
}
diff --git a/test/ExecutionFramework.h b/test/ExecutionFramework.h
index 0b42f9d0..e275147b 100644
--- a/test/ExecutionFramework.h
+++ b/test/ExecutionFramework.h
@@ -147,11 +147,11 @@ public:
static std::pair<bool, std::string> compareAndCreateMessage(bytes const& _result, bytes const& _expectation);
- static bytes encode(bool _value) { return encode(byte(_value)); }
+ static bytes encode(bool _value) { return encode(uint8_t(_value)); }
static bytes encode(int _value) { return encode(u256(_value)); }
static bytes encode(size_t _value) { return encode(u256(_value)); }
static bytes encode(char const* _value) { return encode(std::string(_value)); }
- static bytes encode(byte _value) { return bytes(31, 0) + bytes{_value}; }
+ static bytes encode(uint8_t _value) { return bytes(31, 0) + bytes{_value}; }
static bytes encode(u256 const& _value) { return toBigEndian(_value); }
/// @returns the fixed-point encoding of a rational number with a given
/// number of fractional bits.
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 8d17e56f..87646737 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -1259,14 +1259,14 @@ BOOST_AUTO_TEST_CASE(state_smoke_test)
}
)";
compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("get(uint8)", byte(0x00)), encodeArgs(0));
- ABI_CHECK(callContractFunction("get(uint8)", byte(0x01)), encodeArgs(0));
- ABI_CHECK(callContractFunction("set(uint8,uint256)", byte(0x00), 0x1234), encodeArgs());
- ABI_CHECK(callContractFunction("set(uint8,uint256)", byte(0x01), 0x8765), encodeArgs());
- ABI_CHECK(callContractFunction("get(uint8)", byte( 0x00)), encodeArgs(0x1234));
- ABI_CHECK(callContractFunction("get(uint8)", byte(0x01)), encodeArgs(0x8765));
- ABI_CHECK(callContractFunction("set(uint8,uint256)", byte(0x00), 0x3), encodeArgs());
- ABI_CHECK(callContractFunction("get(uint8)", byte(0x00)), encodeArgs(0x3));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x00)), encodeArgs(0));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x01)), encodeArgs(0));
+ ABI_CHECK(callContractFunction("set(uint8,uint256)", uint8_t(0x00), 0x1234), encodeArgs());
+ ABI_CHECK(callContractFunction("set(uint8,uint256)", uint8_t(0x01), 0x8765), encodeArgs());
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t( 0x00)), encodeArgs(0x1234));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x01)), encodeArgs(0x8765));
+ ABI_CHECK(callContractFunction("set(uint8,uint256)", uint8_t(0x00), 0x3), encodeArgs());
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x00)), encodeArgs(0x3));
}
BOOST_AUTO_TEST_CASE(compound_assign)
@@ -1321,21 +1321,21 @@ BOOST_AUTO_TEST_CASE(simple_mapping)
)";
compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("get(uint8)", byte(0)), encodeArgs(byte(0x00)));
- ABI_CHECK(callContractFunction("get(uint8)", byte(0x01)), encodeArgs(byte(0x00)));
- ABI_CHECK(callContractFunction("get(uint8)", byte(0xa7)), encodeArgs(byte(0x00)));
- callContractFunction("set(uint8,uint8)", byte(0x01), byte(0xa1));
- ABI_CHECK(callContractFunction("get(uint8)", byte(0x00)), encodeArgs(byte(0x00)));
- ABI_CHECK(callContractFunction("get(uint8)", byte(0x01)), encodeArgs(byte(0xa1)));
- ABI_CHECK(callContractFunction("get(uint8)", byte(0xa7)), encodeArgs(byte(0x00)));
- callContractFunction("set(uint8,uint8)", byte(0x00), byte(0xef));
- ABI_CHECK(callContractFunction("get(uint8)", byte(0x00)), encodeArgs(byte(0xef)));
- ABI_CHECK(callContractFunction("get(uint8)", byte(0x01)), encodeArgs(byte(0xa1)));
- ABI_CHECK(callContractFunction("get(uint8)", byte(0xa7)), encodeArgs(byte(0x00)));
- callContractFunction("set(uint8,uint8)", byte(0x01), byte(0x05));
- ABI_CHECK(callContractFunction("get(uint8)", byte(0x00)), encodeArgs(byte(0xef)));
- ABI_CHECK(callContractFunction("get(uint8)", byte(0x01)), encodeArgs(byte(0x05)));
- ABI_CHECK(callContractFunction("get(uint8)", byte(0xa7)), encodeArgs(byte(0x00)));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0)), encodeArgs(uint8_t(0x00)));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x01)), encodeArgs(uint8_t(0x00)));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0xa7)), encodeArgs(uint8_t(0x00)));
+ callContractFunction("set(uint8,uint8)", uint8_t(0x01), uint8_t(0xa1));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x00)), encodeArgs(uint8_t(0x00)));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x01)), encodeArgs(uint8_t(0xa1)));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0xa7)), encodeArgs(uint8_t(0x00)));
+ callContractFunction("set(uint8,uint8)", uint8_t(0x00), uint8_t(0xef));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x00)), encodeArgs(uint8_t(0xef)));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x01)), encodeArgs(uint8_t(0xa1)));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0xa7)), encodeArgs(uint8_t(0x00)));
+ callContractFunction("set(uint8,uint8)", uint8_t(0x01), uint8_t(0x05));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x00)), encodeArgs(uint8_t(0xef)));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x01)), encodeArgs(uint8_t(0x05)));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0xa7)), encodeArgs(uint8_t(0x00)));
}
BOOST_AUTO_TEST_CASE(mapping_state)
@@ -1496,7 +1496,7 @@ BOOST_AUTO_TEST_CASE(mapping_local_assignment)
)";
compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("f()"), encodeArgs(byte(42), byte(0), byte(0), byte(21)));
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(uint8_t(42), uint8_t(0), uint8_t(0), uint8_t(21)));
}
BOOST_AUTO_TEST_CASE(mapping_local_tuple_assignment)
@@ -1519,7 +1519,7 @@ BOOST_AUTO_TEST_CASE(mapping_local_tuple_assignment)
)";
compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("f()"), encodeArgs(byte(42), byte(0), byte(0), byte(21)));
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(uint8_t(42), uint8_t(0), uint8_t(0), uint8_t(21)));
}
BOOST_AUTO_TEST_CASE(mapping_local_compound_assignment)
@@ -1540,7 +1540,7 @@ BOOST_AUTO_TEST_CASE(mapping_local_compound_assignment)
)";
compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("f()"), encodeArgs(byte(42), byte(0), byte(0), byte(21)));
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(uint8_t(42), uint8_t(0), uint8_t(0), uint8_t(21)));
}
BOOST_AUTO_TEST_CASE(mapping_internal_argument)
@@ -1565,10 +1565,10 @@ BOOST_AUTO_TEST_CASE(mapping_internal_argument)
)";
compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("set(uint8,uint8,uint8)", byte(1), byte(21), byte(42)), encodeArgs(byte(0), byte(0)));
- ABI_CHECK(callContractFunction("get(uint8)", byte(1)), encodeArgs(byte(21), byte(42)));
- ABI_CHECK(callContractFunction("set(uint8,uint8,uint8)", byte(1), byte(10), byte(11)), encodeArgs(byte(21), byte(42)));
- ABI_CHECK(callContractFunction("get(uint8)", byte(1)), encodeArgs(byte(10), byte(11)));
+ ABI_CHECK(callContractFunction("set(uint8,uint8,uint8)", uint8_t(1), uint8_t(21), uint8_t(42)), encodeArgs(uint8_t(0), uint8_t(0)));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(1)), encodeArgs(uint8_t(21), uint8_t(42)));
+ ABI_CHECK(callContractFunction("set(uint8,uint8,uint8)", uint8_t(1), uint8_t(10), uint8_t(11)), encodeArgs(uint8_t(21), uint8_t(42)));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(1)), encodeArgs(uint8_t(10), uint8_t(11)));
}
BOOST_AUTO_TEST_CASE(mapping_array_internal_argument)
@@ -1595,10 +1595,10 @@ BOOST_AUTO_TEST_CASE(mapping_array_internal_argument)
)";
compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("set(uint8,uint8,uint8,uint8,uint8)", byte(1), byte(21), byte(22), byte(42), byte(43)), encodeArgs(byte(0), byte(0), byte(0), byte(0)));
- ABI_CHECK(callContractFunction("get(uint8)", byte(1)), encodeArgs(byte(21), byte(22), byte(42), byte(43)));
- ABI_CHECK(callContractFunction("set(uint8,uint8,uint8,uint8,uint8)", byte(1), byte(10), byte(30), byte(11), byte(31)), encodeArgs(byte(21), byte(22), byte(42), byte(43)));
- ABI_CHECK(callContractFunction("get(uint8)", byte(1)), encodeArgs(byte(10), byte(30), byte(11), byte(31)));
+ ABI_CHECK(callContractFunction("set(uint8,uint8,uint8,uint8,uint8)", uint8_t(1), uint8_t(21), uint8_t(22), uint8_t(42), uint8_t(43)), encodeArgs(uint8_t(0), uint8_t(0), uint8_t(0), uint8_t(0)));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(1)), encodeArgs(uint8_t(21), uint8_t(22), uint8_t(42), uint8_t(43)));
+ ABI_CHECK(callContractFunction("set(uint8,uint8,uint8,uint8,uint8)", uint8_t(1), uint8_t(10), uint8_t(30), uint8_t(11), uint8_t(31)), encodeArgs(uint8_t(21), uint8_t(22), uint8_t(42), uint8_t(43)));
+ ABI_CHECK(callContractFunction("get(uint8)", uint8_t(1)), encodeArgs(uint8_t(10), uint8_t(30), uint8_t(11), uint8_t(31)));
}
BOOST_AUTO_TEST_CASE(mapping_internal_return)
@@ -1626,8 +1626,8 @@ BOOST_AUTO_TEST_CASE(mapping_internal_return)
)";
compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("g()"), encodeArgs(byte(0), byte(42), byte(0), byte(0), byte(84), byte (21)));
- ABI_CHECK(callContractFunction("h()"), encodeArgs(byte(0), byte(42), byte(0), byte(0), byte(84), byte (17)));
+ ABI_CHECK(callContractFunction("g()"), encodeArgs(uint8_t(0), uint8_t(42), uint8_t(0), uint8_t(0), uint8_t(84), uint8_t (21)));
+ ABI_CHECK(callContractFunction("h()"), encodeArgs(uint8_t(0), uint8_t(42), uint8_t(0), uint8_t(0), uint8_t(84), uint8_t (17)));
}
BOOST_AUTO_TEST_CASE(structs)
@@ -1819,7 +1819,7 @@ BOOST_AUTO_TEST_CASE(constructor)
}
)";
compileAndRun(sourceCode);
- map<u256, byte> data;
+ map<u256, uint8_t> data;
data[7] = 8;
auto get = [&](u256 const& _x) -> u256
{
@@ -2624,7 +2624,7 @@ BOOST_AUTO_TEST_CASE(ecrecover)
)";
compileAndRun(sourceCode);
u256 h("0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c");
- byte v = 28;
+ uint8_t v = 28;
u256 r("0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f");
u256 s("0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549");
u160 addr("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b");
diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp
index 26b7914f..309cbf0b 100644
--- a/test/libsolidity/SolidityExpressionCompiler.cpp
+++ b/test/libsolidity/SolidityExpressionCompiler.cpp
@@ -180,7 +180,7 @@ BOOST_AUTO_TEST_CASE(literal_true)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH1), 0x1});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x1});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -193,7 +193,7 @@ BOOST_AUTO_TEST_CASE(literal_false)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH1), 0x0});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x0});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE(int_literal)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH10), 0x12, 0x34, 0x56, 0x78, 0x90,
+ bytes expectation({uint8_t(Instruction::PUSH10), 0x12, 0x34, 0x56, 0x78, 0x90,
0x12, 0x34, 0x56, 0x78, 0x90});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -222,7 +222,7 @@ BOOST_AUTO_TEST_CASE(int_with_wei_ether_subdenomination)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH1), 0x1});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x1});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -237,7 +237,7 @@ BOOST_AUTO_TEST_CASE(int_with_szabo_ether_subdenomination)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH5), 0xe8, 0xd4, 0xa5, 0x10, 0x00});
+ bytes expectation({uint8_t(Instruction::PUSH5), 0xe8, 0xd4, 0xa5, 0x10, 0x00});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -253,7 +253,7 @@ BOOST_AUTO_TEST_CASE(int_with_finney_ether_subdenomination)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH7), 0x3, 0x8d, 0x7e, 0xa4, 0xc6, 0x80, 0x00});
+ bytes expectation({uint8_t(Instruction::PUSH7), 0x3, 0x8d, 0x7e, 0xa4, 0xc6, 0x80, 0x00});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -268,7 +268,7 @@ BOOST_AUTO_TEST_CASE(int_with_ether_ether_subdenomination)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH8), 0xd, 0xe0, 0xb6, 0xb3, 0xa7, 0x64, 0x00, 0x00});
+ bytes expectation({uint8_t(Instruction::PUSH8), 0xd, 0xe0, 0xb6, 0xb3, 0xa7, 0x64, 0x00, 0x00});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -281,12 +281,12 @@ BOOST_AUTO_TEST_CASE(comparison)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH1), 0x1, byte(Instruction::ISZERO), byte(Instruction::ISZERO),
- byte(Instruction::PUSH2), 0x11, 0xaa,
- byte(Instruction::PUSH2), 0x10, 0xaa,
- byte(Instruction::LT), byte(Instruction::ISZERO), byte(Instruction::ISZERO),
- byte(Instruction::EQ),
- byte(Instruction::ISZERO)});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x1, uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::PUSH2), 0x11, 0xaa,
+ uint8_t(Instruction::PUSH2), 0x10, 0xaa,
+ uint8_t(Instruction::LT), uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::EQ),
+ uint8_t(Instruction::ISZERO)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -299,23 +299,23 @@ BOOST_AUTO_TEST_CASE(short_circuiting)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH1), 0x12, // 8 + 10
- byte(Instruction::PUSH1), 0x4,
- byte(Instruction::GT),
- byte(Instruction::ISZERO), // after this we have 4 <= 8 + 10
- byte(Instruction::DUP1),
- byte(Instruction::PUSH1), 0x11,
- byte(Instruction::JUMPI), // short-circuit if it is true
- byte(Instruction::POP),
- byte(Instruction::PUSH1), 0x2,
- byte(Instruction::PUSH1), 0x9,
- byte(Instruction::EQ),
- byte(Instruction::ISZERO), // after this we have 9 != 2
- byte(Instruction::JUMPDEST),
- byte(Instruction::ISZERO), byte(Instruction::ISZERO),
- byte(Instruction::PUSH1), 0x1, byte(Instruction::ISZERO), byte(Instruction::ISZERO),
- byte(Instruction::EQ),
- byte(Instruction::ISZERO)});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x12, // 8 + 10
+ uint8_t(Instruction::PUSH1), 0x4,
+ uint8_t(Instruction::GT),
+ uint8_t(Instruction::ISZERO), // after this we have 4 <= 8 + 10
+ uint8_t(Instruction::DUP1),
+ uint8_t(Instruction::PUSH1), 0x11,
+ uint8_t(Instruction::JUMPI), // short-circuit if it is true
+ uint8_t(Instruction::POP),
+ uint8_t(Instruction::PUSH1), 0x2,
+ uint8_t(Instruction::PUSH1), 0x9,
+ uint8_t(Instruction::EQ),
+ uint8_t(Instruction::ISZERO), // after this we have 9 != 2
+ uint8_t(Instruction::JUMPDEST),
+ uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::PUSH1), 0x1, uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::EQ),
+ uint8_t(Instruction::ISZERO)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -327,37 +327,37 @@ BOOST_AUTO_TEST_CASE(arithmetic)
}
)";
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}});
- bytes expectation({byte(Instruction::PUSH1), 0x1,
- byte(Instruction::PUSH1), 0x2,
- byte(Instruction::PUSH1), 0x3,
- byte(Instruction::PUSH1), 0x4,
- byte(Instruction::PUSH1), 0x5,
- byte(Instruction::PUSH1), 0x6,
- byte(Instruction::PUSH1), 0x7,
- byte(Instruction::PUSH1), 0x8,
- byte(Instruction::DUP9),
- byte(Instruction::XOR),
- byte(Instruction::AND),
- byte(Instruction::OR),
- byte(Instruction::SUB),
- byte(Instruction::ADD),
- byte(Instruction::DUP2),
- byte(Instruction::ISZERO),
- byte(Instruction::ISZERO),
- byte(Instruction::PUSH1), 0x1d,
- byte(Instruction::JUMPI),
- byte(Instruction::INVALID),
- byte(Instruction::JUMPDEST),
- byte(Instruction::MOD),
- byte(Instruction::DUP2),
- byte(Instruction::ISZERO),
- byte(Instruction::ISZERO),
- byte(Instruction::PUSH1), 0x26,
- byte(Instruction::JUMPI),
- byte(Instruction::INVALID),
- byte(Instruction::JUMPDEST),
- byte(Instruction::DIV),
- byte(Instruction::MUL)});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x1,
+ uint8_t(Instruction::PUSH1), 0x2,
+ uint8_t(Instruction::PUSH1), 0x3,
+ uint8_t(Instruction::PUSH1), 0x4,
+ uint8_t(Instruction::PUSH1), 0x5,
+ uint8_t(Instruction::PUSH1), 0x6,
+ uint8_t(Instruction::PUSH1), 0x7,
+ uint8_t(Instruction::PUSH1), 0x8,
+ uint8_t(Instruction::DUP9),
+ uint8_t(Instruction::XOR),
+ uint8_t(Instruction::AND),
+ uint8_t(Instruction::OR),
+ uint8_t(Instruction::SUB),
+ uint8_t(Instruction::ADD),
+ uint8_t(Instruction::DUP2),
+ uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::PUSH1), 0x1d,
+ uint8_t(Instruction::JUMPI),
+ uint8_t(Instruction::INVALID),
+ uint8_t(Instruction::JUMPDEST),
+ uint8_t(Instruction::MOD),
+ uint8_t(Instruction::DUP2),
+ uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::PUSH1), 0x26,
+ uint8_t(Instruction::JUMPI),
+ uint8_t(Instruction::INVALID),
+ uint8_t(Instruction::JUMPDEST),
+ uint8_t(Instruction::DIV),
+ uint8_t(Instruction::MUL)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -370,13 +370,13 @@ BOOST_AUTO_TEST_CASE(unary_operators)
)";
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}});
- bytes expectation({byte(Instruction::PUSH1), 0x2,
- byte(Instruction::DUP2),
- byte(Instruction::PUSH1), 0x0,
- byte(Instruction::SUB),
- byte(Instruction::NOT),
- byte(Instruction::EQ),
- byte(Instruction::ISZERO)});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x2,
+ uint8_t(Instruction::DUP2),
+ uint8_t(Instruction::PUSH1), 0x0,
+ uint8_t(Instruction::SUB),
+ uint8_t(Instruction::NOT),
+ uint8_t(Instruction::EQ),
+ uint8_t(Instruction::ISZERO)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -390,47 +390,47 @@ BOOST_AUTO_TEST_CASE(unary_inc_dec)
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "x"}});
// Stack: a, x
- bytes expectation({byte(Instruction::DUP2),
- byte(Instruction::DUP1),
- byte(Instruction::PUSH1), 0x1,
- byte(Instruction::ADD),
+ bytes expectation({uint8_t(Instruction::DUP2),
+ uint8_t(Instruction::DUP1),
+ uint8_t(Instruction::PUSH1), 0x1,
+ uint8_t(Instruction::ADD),
// Stack here: a x a (a+1)
- byte(Instruction::SWAP3),
- byte(Instruction::POP), // first ++
+ uint8_t(Instruction::SWAP3),
+ uint8_t(Instruction::POP), // first ++
// Stack here: (a+1) x a
- byte(Instruction::DUP3),
- byte(Instruction::PUSH1), 0x1,
- byte(Instruction::ADD),
+ uint8_t(Instruction::DUP3),
+ uint8_t(Instruction::PUSH1), 0x1,
+ uint8_t(Instruction::ADD),
// Stack here: (a+1) x a (a+2)
- byte(Instruction::SWAP3),
- byte(Instruction::POP),
+ uint8_t(Instruction::SWAP3),
+ uint8_t(Instruction::POP),
// Stack here: (a+2) x a
- byte(Instruction::DUP3), // second ++
- byte(Instruction::XOR),
+ uint8_t(Instruction::DUP3), // second ++
+ uint8_t(Instruction::XOR),
// Stack here: (a+2) x a^(a+2)
- byte(Instruction::DUP3),
- byte(Instruction::DUP1),
- byte(Instruction::PUSH1), 0x1,
- byte(Instruction::SWAP1),
- byte(Instruction::SUB),
+ uint8_t(Instruction::DUP3),
+ uint8_t(Instruction::DUP1),
+ uint8_t(Instruction::PUSH1), 0x1,
+ uint8_t(Instruction::SWAP1),
+ uint8_t(Instruction::SUB),
// Stack here: (a+2) x a^(a+2) (a+2) (a+1)
- byte(Instruction::SWAP4),
- byte(Instruction::POP), // first --
- byte(Instruction::XOR),
+ uint8_t(Instruction::SWAP4),
+ uint8_t(Instruction::POP), // first --
+ uint8_t(Instruction::XOR),
// Stack here: (a+1) x a^(a+2)^(a+2)
- byte(Instruction::DUP3),
- byte(Instruction::PUSH1), 0x1,
- byte(Instruction::SWAP1),
- byte(Instruction::SUB),
+ uint8_t(Instruction::DUP3),
+ uint8_t(Instruction::PUSH1), 0x1,
+ uint8_t(Instruction::SWAP1),
+ uint8_t(Instruction::SUB),
// Stack here: (a+1) x a^(a+2)^(a+2) a
- byte(Instruction::SWAP3),
- byte(Instruction::POP), // second ++
+ uint8_t(Instruction::SWAP3),
+ uint8_t(Instruction::POP), // second ++
// Stack here: a x a^(a+2)^(a+2)
- byte(Instruction::DUP3), // will change
- byte(Instruction::XOR),
- byte(Instruction::SWAP1),
- byte(Instruction::POP),
- byte(Instruction::DUP1)});
+ uint8_t(Instruction::DUP3), // will change
+ uint8_t(Instruction::XOR),
+ uint8_t(Instruction::SWAP1),
+ uint8_t(Instruction::POP),
+ uint8_t(Instruction::DUP1)});
// Stack here: a x a^(a+2)^(a+2)^a
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -445,16 +445,16 @@ BOOST_AUTO_TEST_CASE(assignment)
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "b"}});
// Stack: a, b
- bytes expectation({byte(Instruction::PUSH1), 0x2,
- byte(Instruction::DUP2),
- byte(Instruction::DUP4),
- byte(Instruction::ADD),
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x2,
+ uint8_t(Instruction::DUP2),
+ uint8_t(Instruction::DUP4),
+ uint8_t(Instruction::ADD),
// Stack here: a b 2 a+b
- byte(Instruction::SWAP3),
- byte(Instruction::POP),
- byte(Instruction::DUP3),
+ uint8_t(Instruction::SWAP3),
+ uint8_t(Instruction::POP),
+ uint8_t(Instruction::DUP3),
// Stack here: a+b b 2 a+b
- byte(Instruction::MUL)});
+ uint8_t(Instruction::MUL)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -467,7 +467,7 @@ BOOST_AUTO_TEST_CASE(negative_literals_8bits)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation(bytes({byte(Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x80));
+ bytes expectation(bytes({uint8_t(Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x80));
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -480,7 +480,7 @@ BOOST_AUTO_TEST_CASE(negative_literals_16bits)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation(bytes({byte(Instruction::PUSH32)}) + bytes(30, 0xff) + bytes{0xf5, 0x43});
+ bytes expectation(bytes({uint8_t(Instruction::PUSH32)}) + bytes(30, 0xff) + bytes{0xf5, 0x43});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -495,7 +495,7 @@ BOOST_AUTO_TEST_CASE(intermediately_overflowing_literals)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation(bytes({byte(Instruction::PUSH1), 0xbf}));
+ bytes expectation(bytes({uint8_t(Instruction::PUSH1), 0xbf}));
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -514,8 +514,8 @@ BOOST_AUTO_TEST_CASE(blockhash)
bytes code = compileFirstExpression(sourceCode, {}, {}, {make_shared<MagicVariableDeclaration>("blockhash", blockhashFun)});
- bytes expectation({byte(Instruction::PUSH1), 0x03,
- byte(Instruction::BLOCKHASH)});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x03,
+ uint8_t(Instruction::BLOCKHASH)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -533,7 +533,7 @@ BOOST_AUTO_TEST_CASE(gas_left)
{make_shared<MagicVariableDeclaration>("gasleft", make_shared<FunctionType>(strings(), strings{"uint256"}, FunctionType::Kind::GasLeft))}
);
- bytes expectation = bytes({byte(Instruction::GAS)});
+ bytes expectation = bytes({uint8_t(Instruction::GAS)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
diff --git a/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_payable.sol b/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_payable.sol
new file mode 100644
index 00000000..75f7a953
--- /dev/null
+++ b/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_payable.sol
@@ -0,0 +1,10 @@
+contract C {
+ function h() external {
+ }
+ function f() view external returns (bytes4) {
+ function () payable external g = this.h;
+ return g.selector;
+ }
+}
+// ----
+// TypeError: (105-144): Type function () external is not implicitly convertible to expected type function () payable external.
diff --git a/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_pure.sol b/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_pure.sol
new file mode 100644
index 00000000..8d1b08aa
--- /dev/null
+++ b/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_pure.sol
@@ -0,0 +1,10 @@
+contract C {
+ function h() external {
+ }
+ function f() view external returns (bytes4) {
+ function () pure external g = this.h;
+ return g.selector;
+ }
+}
+// ----
+// TypeError: (105-141): Type function () external is not implicitly convertible to expected type function () pure external.
diff --git a/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_view.sol b/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_view.sol
new file mode 100644
index 00000000..535d6c77
--- /dev/null
+++ b/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_view.sol
@@ -0,0 +1,10 @@
+contract C {
+ function h() external {
+ }
+ function f() view external returns (bytes4) {
+ function () view external g = this.h;
+ return g.selector;
+ }
+}
+// ----
+// TypeError: (105-141): Type function () external is not implicitly convertible to expected type function () view external.
diff --git a/test/libsolidity/syntaxTests/conversion/function_type_payable_nonpayable.sol b/test/libsolidity/syntaxTests/conversion/function_type_payable_nonpayable.sol
new file mode 100644
index 00000000..299d7e30
--- /dev/null
+++ b/test/libsolidity/syntaxTests/conversion/function_type_payable_nonpayable.sol
@@ -0,0 +1,8 @@
+contract C {
+ function h() payable external {
+ }
+ function f() view external returns (bytes4) {
+ function () external g = this.h;
+ return g.selector;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/conversion/function_type_payable_pure.sol b/test/libsolidity/syntaxTests/conversion/function_type_payable_pure.sol
new file mode 100644
index 00000000..78bada51
--- /dev/null
+++ b/test/libsolidity/syntaxTests/conversion/function_type_payable_pure.sol
@@ -0,0 +1,10 @@
+contract C {
+ function h() payable external {
+ }
+ function f() view external returns (bytes4) {
+ function () pure external g = this.h;
+ return g.selector;
+ }
+}
+// ----
+// TypeError: (113-149): Type function () payable external is not implicitly convertible to expected type function () pure external.
diff --git a/test/libsolidity/syntaxTests/conversion/function_type_payable_view.sol b/test/libsolidity/syntaxTests/conversion/function_type_payable_view.sol
new file mode 100644
index 00000000..f12cb301
--- /dev/null
+++ b/test/libsolidity/syntaxTests/conversion/function_type_payable_view.sol
@@ -0,0 +1,10 @@
+contract C {
+ function h() payable external {
+ }
+ function f() view external returns (bytes4) {
+ function () view external g = this.h;
+ return g.selector;
+ }
+}
+// ----
+// TypeError: (113-149): Type function () payable external is not implicitly convertible to expected type function () view external.
diff --git a/test/libsolidity/syntaxTests/conversion/function_type_pure_nonpayable.sol b/test/libsolidity/syntaxTests/conversion/function_type_pure_nonpayable.sol
new file mode 100644
index 00000000..7742e0c1
--- /dev/null
+++ b/test/libsolidity/syntaxTests/conversion/function_type_pure_nonpayable.sol
@@ -0,0 +1,8 @@
+contract C {
+ function h() pure external {
+ }
+ function f() view external returns (bytes4) {
+ function () external g = this.h;
+ return g.selector;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/conversion/function_type_pure_payable.sol b/test/libsolidity/syntaxTests/conversion/function_type_pure_payable.sol
new file mode 100644
index 00000000..cd4e9b4e
--- /dev/null
+++ b/test/libsolidity/syntaxTests/conversion/function_type_pure_payable.sol
@@ -0,0 +1,10 @@
+contract C {
+ function h() pure external {
+ }
+ function f() view external returns (bytes4) {
+ function () payable external g = this.h;
+ return g.selector;
+ }
+}
+// ----
+// TypeError: (110-149): Type function () pure external is not implicitly convertible to expected type function () payable external.
diff --git a/test/libsolidity/syntaxTests/conversion/function_type_pure_view.sol b/test/libsolidity/syntaxTests/conversion/function_type_pure_view.sol
new file mode 100644
index 00000000..578ecdbd
--- /dev/null
+++ b/test/libsolidity/syntaxTests/conversion/function_type_pure_view.sol
@@ -0,0 +1,8 @@
+contract C {
+ function h() pure external {
+ }
+ function f() view external returns (bytes4) {
+ function () view external g = this.h;
+ return g.selector;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/conversion/function_type_same.sol b/test/libsolidity/syntaxTests/conversion/function_type_same.sol
new file mode 100644
index 00000000..c5ebe1ca
--- /dev/null
+++ b/test/libsolidity/syntaxTests/conversion/function_type_same.sol
@@ -0,0 +1,14 @@
+contract C {
+ int dummy;
+ function h_nonpayable() external { dummy = 1; }
+ function h_payable() payable external {}
+ function h_view() view external { dummy; }
+ function h_pure() pure external {}
+ function f() view external {
+ function () external g_nonpayable = this.h_nonpayable; g_nonpayable;
+ function () payable external g_payable = this.h_payable; g_payable;
+ function () view external g_view = this.h_view; g_view;
+ function () pure external g_pure = this.h_pure; g_pure;
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/conversion/function_type_view_nonpayable.sol b/test/libsolidity/syntaxTests/conversion/function_type_view_nonpayable.sol
new file mode 100644
index 00000000..f52aece0
--- /dev/null
+++ b/test/libsolidity/syntaxTests/conversion/function_type_view_nonpayable.sol
@@ -0,0 +1,10 @@
+contract C {
+ int dummy;
+ function h() view external {
+ dummy;
+ }
+ function f() view external returns (bytes4) {
+ function () external g = this.h;
+ return g.selector;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/conversion/function_type_view_payable.sol b/test/libsolidity/syntaxTests/conversion/function_type_view_payable.sol
new file mode 100644
index 00000000..3bf4bac2
--- /dev/null
+++ b/test/libsolidity/syntaxTests/conversion/function_type_view_payable.sol
@@ -0,0 +1,10 @@
+contract C {
+ function h() view external {
+ }
+ function f() view external returns (bytes4) {
+ function () payable external g = this.h;
+ return g.selector;
+ }
+}
+// ----
+// TypeError: (110-149): Type function () view external is not implicitly convertible to expected type function () payable external.
diff --git a/test/libsolidity/syntaxTests/conversion/function_type_view_pure.sol b/test/libsolidity/syntaxTests/conversion/function_type_view_pure.sol
new file mode 100644
index 00000000..c567a2c8
--- /dev/null
+++ b/test/libsolidity/syntaxTests/conversion/function_type_view_pure.sol
@@ -0,0 +1,10 @@
+contract C {
+ function h() view external {
+ }
+ function f() view external returns (bytes4) {
+ function () pure external g = this.h;
+ return g.selector;
+ }
+}
+// ----
+// TypeError: (110-146): Type function () view external is not implicitly convertible to expected type function () pure external.
diff --git a/test/libsolidity/syntaxTests/types/rational_negative_numerator_negative_exp.sol b/test/libsolidity/syntaxTests/types/rational_negative_numerator_negative_exp.sol
new file mode 100644
index 00000000..b694992c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/rational_negative_numerator_negative_exp.sol
@@ -0,0 +1,5 @@
+contract C {
+ function f() public pure returns (int) {
+ return (-1 / 2) ** -1;
+ }
+}
diff --git a/test/libyul/Inliner.cpp b/test/libyul/Inliner.cpp
index 44c6411a..4ed52b47 100644
--- a/test/libyul/Inliner.cpp
+++ b/test/libyul/Inliner.cpp
@@ -49,10 +49,10 @@ string inlinableFunctions(string const& _source)
InlinableExpressionFunctionFinder funFinder;
funFinder(ast);
- return boost::algorithm::join(
- funFinder.inlinableFunctions() | boost::adaptors::map_keys,
- ","
- );
+ vector<string> functionNames;
+ for (auto const& f: funFinder.inlinableFunctions())
+ functionNames.emplace_back(f.first.str());
+ return boost::algorithm::join(functionNames, ",");
}
}
diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp
index 83c54959..68fc9f4f 100644
--- a/test/tools/yulopti.cpp
+++ b/test/tools/yulopti.cpp
@@ -121,7 +121,8 @@ public:
disambiguated = true;
}
cout << "(q)quit/(f)flatten/(c)se/(x)plit/(j)oin/(g)rouper/(h)oister/" << endl;
- cout << " (e)xpr inline/(i)nline/(s)implify/(u)nusedprune/ss(a) transform/(r)edundant assign elim.? ";
+ cout << " (e)xpr inline/(i)nline/(s)implify/(u)nusedprune/ss(a) transform/" << endl;
+ cout << " (r)edundant assign elim./re(m)aterializer? ";
cout.flush();
int option = readStandardInputChar();
cout << ' ' << char(option) << endl;
@@ -165,6 +166,9 @@ public:
case 'r':
RedundantAssignEliminator::run(*m_ast);
break;
+ case 'm':
+ Rematerialiser{}(*m_ast);
+ break;
default:
cout << "Unknown option." << endl;
}