Skip to content

Commit a697123

Browse files
Merge branch 'ethereum:develop' into colors
2 parents 2ff7103 + 55467c1 commit a697123

File tree

145 files changed

+3296
-831
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

145 files changed

+3296
-831
lines changed

Changelog.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,23 @@ Compiler Features:
1414
* SMTChecker: Add constraints to better correlate ``address(this).balance`` and ``msg.value``.
1515
* SMTChecker: Support the ``value`` option for external function calls.
1616
* SMTChecker: Support constants via modules.
17+
* SMTChecker: Support user defined value types.
1718

1819

1920
Bugfixes:
2021
* Code Generator: Fix ICE on assigning to calldata structs and statically-sized calldata arrays in inline assembly.
2122
* Code Generator: Use stable source order for ABI functions.
22-
* Commandline Interface: Report optimizer options as invalid in Standard JSON and linker modes instead of ignoring them.
2323
* Commandline Interface: Disallow the ``--experimental-via-ir`` option in Standard JSON, Assembler and Linker modes.
24-
* Opcode Optimizer: Prevent the optimizer from running multiple times to avoid potential bytecode differences for referenced code.
24+
* Commandline Interface: Report optimizer options as invalid in Standard JSON and linker modes instead of ignoring them.
2525
* Name Resolver: Fix that when importing an aliased symbol using ``import {AliasedName} from "a.sol"`` it would use the original name of the symbol and not the aliased one.
26+
* Opcode Optimizer: Prevent the optimizer from running multiple times to avoid potential bytecode differences for referenced code.
2627
* Parser: Properly check for multiple SPDX license identifiers next to each other and validate them.
28+
* SMTChecker: Fix BMC's constraints regarding internal functions.
2729
* SMTChecker: Fix false negative caused by ``push`` on storage array references returned by internal functions.
2830
* SMTChecker: Fix false positive in external calls from constructors.
2931
* SMTChecker: Fix internal error on some multi-source uses of ``abi.*``, cryptographic functions and constants.
30-
* SMTChecker: Fix BMC's constraints regarding internal functions.
32+
* Standard JSON: Fix non-fatal errors in Yul mode being discarded if followed by a fatal error.
33+
* Type Checker: Correct wrong error message in inline assembly complaining about ``.slot`` or ``.offset` not valid when actually ``.length`` was used.
3134
* Type Checker: Disallow modifier declarations and definitions in interfaces.
3235
* Yul Optimizer: Fix a crash in LoadResolver, when ``keccak256`` has particular non-identifier arguments.
3336

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ Please follow the
7676
if you want to help.
7777

7878
You can find our current feature and bug priorities for forthcoming
79-
releases [in the projects section](https://github.com/ethereum/solidity/projects).
79+
releases in the [projects section](https://github.com/ethereum/solidity/projects).
8080

8181
## Maintainers
8282
* [@axic](https://github.com/axic)

docs/yul.rst

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,18 +174,40 @@ whitespace, i.e. there is no terminating ``;`` or newline required.
174174
Literals
175175
--------
176176

177-
As literals, you can use integer constants in decimal or hexadecimal notation
178-
or strings as ASCII (`"abc"`) or HEX strings (`hex"616263"`) of up to
179-
32 bytes length.
177+
As literals, you can use:
178+
179+
- Integer constants in decimal or hexadecimal notation.
180+
181+
- ASCII strings (e.g. ``"abc"``), which may contain hex escapes ``\xNN`` and Unicode escapes ``\uNNNN`` where ``N`` are hexadecimal digits.
182+
183+
- Hex strings (e.g. ``hex"616263"``).
184+
185+
In the EVM dialect of Yul, literals represent 256-bit words as follows:
186+
187+
- Decimal or hexadecimal constants must be less than ``2**256``.
188+
They represent the 256-bit word with that value as an unsigned integer in big endian encoding.
189+
190+
- An ASCII string is first viewed as a byte sequence, by viewing
191+
a non-escape ASCII character as a single byte whose value is the ASCII code,
192+
an escape ``\xNN`` as single byte with that value, and
193+
an escape ``\uNNNN`` as the UTF-8 sequence of bytes for that code point.
194+
The byte sequence must not exceed 32 bytes.
195+
The byte sequence is padded with zeros on the right to reach 32 bytes in length;
196+
in other words, the string is stored left-aligned.
197+
The padded byte sequence represents a 256-bit word whose most significant 8 bits are the ones from the first byte,
198+
i.e. the bytes are interpreted in big endian form.
199+
200+
- A hex string is first viewed as a byte sequence, by viewing
201+
each pair of contiguous hex digits as a byte.
202+
The byte sequence must not exceed 32 bytes (i.e. 64 hex digits), and is treated as above.
180203

181204
When compiling for the EVM, this will be translated into an
182205
appropriate ``PUSHi`` instruction. In the following example,
183206
``3`` and ``2`` are added resulting in 5 and then the
184207
bitwise ``and`` with the string "abc" is computed.
185208
The final value is assigned to a local variable called ``x``.
186209

187-
Strings are stored left-aligned and cannot be longer than 32 bytes.
188-
The limit does not apply to string literals passed to builtin functions that require
210+
The 32-byte limit above does not apply to string literals passed to builtin functions that require
189211
literal arguments (e.g. ``setimmutable`` or ``loadimmutable``). Those strings never end up in the
190212
generated bytecode.
191213

libevmasm/Assembly.cpp

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@
3636

3737
#include <json/json.h>
3838

39-
#include <fstream>
4039
#include <range/v3/algorithm/any_of.hpp>
40+
#include <range/v3/view/enumerate.hpp>
41+
42+
#include <fstream>
43+
#include <limits>
4144

4245
using namespace std;
4346
using namespace solidity;
@@ -56,7 +59,7 @@ AssemblyItem const& Assembly::append(AssemblyItem const& _i)
5659
return m_items.back();
5760
}
5861

59-
unsigned Assembly::bytesRequired(unsigned subTagSize) const
62+
unsigned Assembly::codeSize(unsigned subTagSize) const
6063
{
6164
for (unsigned tagSize = subTagSize; true; ++tagSize)
6265
{
@@ -66,7 +69,7 @@ unsigned Assembly::bytesRequired(unsigned subTagSize) const
6669

6770
for (AssemblyItem const& i: m_items)
6871
ret += i.bytesRequired(tagSize);
69-
if (util::bytesRequired(ret) <= tagSize)
72+
if (numberEncodingSize(ret) <= tagSize)
7073
return static_cast<unsigned>(ret);
7174
}
7275
}
@@ -177,7 +180,7 @@ void Assembly::assemblyStream(ostream& _out, string const& _prefix, StringMap co
177180
_out << _prefix << "stop" << endl;
178181
for (auto const& i: m_data)
179182
if (u256(i.first) >= m_subs.size())
180-
_out << _prefix << "data_" << toHex(u256(i.first)) << " " << toHex(i.second) << endl;
183+
_out << _prefix << "data_" << toHex(u256(i.first)) << " " << util::toHex(i.second) << endl;
181184

182185
for (size_t i = 0; i < m_subs.size(); ++i)
183186
{
@@ -188,7 +191,7 @@ void Assembly::assemblyStream(ostream& _out, string const& _prefix, StringMap co
188191
}
189192

190193
if (m_auxiliaryData.size() > 0)
191-
_out << endl << _prefix << "auxdata: 0x" << toHex(m_auxiliaryData) << endl;
194+
_out << endl << _prefix << "auxdata: 0x" << util::toHex(m_auxiliaryData) << endl;
192195
}
193196

194197
string Assembly::assemblyString(StringMap const& _sourceCodes) const
@@ -308,7 +311,7 @@ Json::Value Assembly::assemblyJSON(map<string, unsigned> const& _sourceIndices)
308311
collection.append(createJsonValue("PUSH data", sourceIndex, i.location().start, i.location().end, toStringInHex(i.data())));
309312
break;
310313
case VerbatimBytecode:
311-
collection.append(createJsonValue("VERBATIM", sourceIndex, i.location().start, i.location().end, toHex(i.verbatimData())));
314+
collection.append(createJsonValue("VERBATIM", sourceIndex, i.location().start, i.location().end, util::toHex(i.verbatimData())));
312315
break;
313316
default:
314317
assertThrow(false, InvalidOpcode, "");
@@ -320,7 +323,7 @@ Json::Value Assembly::assemblyJSON(map<string, unsigned> const& _sourceIndices)
320323
Json::Value& data = root[".data"] = Json::objectValue;
321324
for (auto const& i: m_data)
322325
if (u256(i.first) >= m_subs.size())
323-
data[toStringInHex((u256)i.first)] = toHex(i.second);
326+
data[toStringInHex((u256)i.first)] = util::toHex(i.second);
324327

325328
for (size_t i = 0; i < m_subs.size(); ++i)
326329
{
@@ -331,7 +334,7 @@ Json::Value Assembly::assemblyJSON(map<string, unsigned> const& _sourceIndices)
331334
}
332335

333336
if (m_auxiliaryData.size() > 0)
334-
root[".auxdata"] = toHex(m_auxiliaryData);
337+
root[".auxdata"] = util::toHex(m_auxiliaryData);
335338

336339
return root;
337340
}
@@ -589,20 +592,20 @@ LinkerObject const& Assembly::assemble() const
589592
"Cannot push and assign immutables in the same assembly subroutine."
590593
);
591594

592-
unsigned bytesRequiredForCode = bytesRequired(static_cast<unsigned>(subTagSize));
595+
unsigned bytesRequiredForCode = codeSize(static_cast<unsigned>(subTagSize));
593596
m_tagPositionsInBytecode = vector<size_t>(m_usedTags, numeric_limits<size_t>::max());
594597
map<size_t, pair<size_t, size_t>> tagRef;
595598
multimap<h256, unsigned> dataRef;
596599
multimap<size_t, size_t> subRef;
597600
vector<unsigned> sizeRef; ///< Pointers to code locations where the size of the program is inserted
598-
unsigned bytesPerTag = util::bytesRequired(bytesRequiredForCode);
601+
unsigned bytesPerTag = numberEncodingSize(bytesRequiredForCode);
599602
uint8_t tagPush = static_cast<uint8_t>(pushInstruction(bytesPerTag));
600603

601604
unsigned bytesRequiredIncludingData = bytesRequiredForCode + 1 + static_cast<unsigned>(m_auxiliaryData.size());
602605
for (auto const& sub: m_subs)
603606
bytesRequiredIncludingData += static_cast<unsigned>(sub->assemble().bytecode.size());
604607

605-
unsigned bytesPerDataRef = util::bytesRequired(bytesRequiredIncludingData);
608+
unsigned bytesPerDataRef = numberEncodingSize(bytesRequiredIncludingData);
606609
uint8_t dataRefPush = static_cast<uint8_t>(pushInstruction(bytesPerDataRef));
607610
ret.bytecode.reserve(bytesRequiredIncludingData);
608611

@@ -619,7 +622,7 @@ LinkerObject const& Assembly::assemble() const
619622
break;
620623
case Push:
621624
{
622-
unsigned b = max<unsigned>(1, util::bytesRequired(i.data()));
625+
unsigned b = max<unsigned>(1, numberEncodingSize(i.data()));
623626
ret.bytecode.push_back(static_cast<uint8_t>(pushInstruction(b)));
624627
ret.bytecode.resize(ret.bytecode.size() + b);
625628
bytesRef byr(&ret.bytecode.back() + 1 - b, b);
@@ -649,7 +652,7 @@ LinkerObject const& Assembly::assemble() const
649652
assertThrow(i.data() <= numeric_limits<size_t>::max(), AssemblyException, "");
650653
auto s = subAssemblyById(static_cast<size_t>(i.data()))->assemble().bytecode.size();
651654
i.setPushedValue(u256(s));
652-
unsigned b = max<unsigned>(1, util::bytesRequired(s));
655+
unsigned b = max<unsigned>(1, numberEncodingSize(s));
653656
ret.bytecode.push_back(static_cast<uint8_t>(pushInstruction(b)));
654657
ret.bytecode.resize(ret.bytecode.size() + b);
655658
bytesRef byr(&ret.bytecode.back() + 1 - b, b);
@@ -754,15 +757,23 @@ LinkerObject const& Assembly::assemble() const
754757
assertThrow(tagId < tagPositions.size(), AssemblyException, "Reference to non-existing tag.");
755758
size_t pos = tagPositions[tagId];
756759
assertThrow(pos != numeric_limits<size_t>::max(), AssemblyException, "Reference to tag without position.");
757-
assertThrow(util::bytesRequired(pos) <= bytesPerTag, AssemblyException, "Tag too large for reserved space.");
760+
assertThrow(numberEncodingSize(pos) <= bytesPerTag, AssemblyException, "Tag too large for reserved space.");
758761
bytesRef r(ret.bytecode.data() + i.first, bytesPerTag);
759762
toBigEndian(pos, r);
760763
}
761764
for (auto const& [name, tagInfo]: m_namedTags)
762765
{
763766
size_t position = m_tagPositionsInBytecode.at(tagInfo.id);
767+
optional<size_t> tagIndex;
768+
for (auto&& [index, item]: m_items | ranges::views::enumerate)
769+
if (item.type() == Tag && static_cast<size_t>(item.data()) == tagInfo.id)
770+
{
771+
tagIndex = index;
772+
break;
773+
}
764774
ret.functionDebugData[name] = {
765775
position == numeric_limits<size_t>::max() ? nullopt : optional<size_t>{position},
776+
tagIndex,
766777
tagInfo.sourceID,
767778
tagInfo.params,
768779
tagInfo.returns

libevmasm/Assembly.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ class Assembly
167167
/// that are referenced in a super-assembly.
168168
std::map<u256, u256> const& optimiseInternal(OptimiserSettings const& _settings, std::set<size_t> _tagsReferencedFromOutside);
169169

170-
unsigned bytesRequired(unsigned subTagSize) const;
170+
unsigned codeSize(unsigned subTagSize) const;
171171

172172
private:
173173
static Json::Value createJsonValue(

libevmasm/AssemblyItem.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@
2121
#include <libevmasm/Assembly.h>
2222

2323
#include <libsolutil/CommonData.h>
24+
#include <libsolutil/Numeric.h>
2425
#include <libsolutil/StringUtils.h>
2526
#include <libsolutil/FixedHash.h>
2627
#include <liblangutil/SourceLocation.h>
2728

2829
#include <fstream>
30+
#include <limits>
2931

3032
using namespace std;
3133
using namespace solidity;
@@ -71,7 +73,7 @@ size_t AssemblyItem::bytesRequired(size_t _addressLength) const
7173
case Tag: // 1 byte for the JUMPDEST
7274
return 1;
7375
case Push:
74-
return 1 + max<size_t>(1, util::bytesRequired(data()));
76+
return 1 + max<size_t>(1, numberEncodingSize(data()));
7577
case PushSubSize:
7678
case PushProgramSize:
7779
return 1 + 4; // worst case: a 16MB program
@@ -189,7 +191,7 @@ string AssemblyItem::toAssemblyText(Assembly const& _assembly) const
189191
break;
190192
}
191193
case Push:
192-
text = toHex(util::toCompactBigEndian(data(), 1), util::HexPrefix::Add);
194+
text = toHex(toCompactBigEndian(data(), 1), util::HexPrefix::Add);
193195
break;
194196
case PushTag:
195197
{
@@ -207,7 +209,7 @@ string AssemblyItem::toAssemblyText(Assembly const& _assembly) const
207209
text = string("tag_") + to_string(static_cast<size_t>(data())) + ":";
208210
break;
209211
case PushData:
210-
text = string("data_") + util::toHex(data());
212+
text = string("data_") + toHex(data());
211213
break;
212214
case PushSub:
213215
case PushSubSize:
@@ -226,16 +228,16 @@ string AssemblyItem::toAssemblyText(Assembly const& _assembly) const
226228
text = string("bytecodeSize");
227229
break;
228230
case PushLibraryAddress:
229-
text = string("linkerSymbol(\"") + util::toHex(data()) + string("\")");
231+
text = string("linkerSymbol(\"") + toHex(data()) + string("\")");
230232
break;
231233
case PushDeployTimeAddress:
232234
text = string("deployTimeAddress()");
233235
break;
234236
case PushImmutable:
235-
text = string("immutable(\"") + toHex(util::toCompactBigEndian(data(), 1), util::HexPrefix::Add) + "\")";
237+
text = string("immutable(\"") + "0x" + util::toHex(toCompactBigEndian(data(), 1)) + "\")";
236238
break;
237239
case AssignImmutable:
238-
text = string("assignImmutable(\"") + toHex(util::toCompactBigEndian(data(), 1), util::HexPrefix::Add) + "\")";
240+
text = string("assignImmutable(\"") + "0x" + util::toHex(toCompactBigEndian(data(), 1)) + "\")";
239241
break;
240242
case UndefinedItem:
241243
assertThrow(false, AssemblyException, "Invalid assembly item.");

libevmasm/BlockDeduplicator.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#pragma once
2626

2727
#include <libsolutil/Common.h>
28+
#include <libsolutil/Numeric.h>
29+
2830

2931
#include <cstddef>
3032
#include <vector>

libevmasm/ConstantOptimiser.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ bigint LiteralMethod::gasNeeded() const
133133
return combineGas(
134134
simpleRunGas({Instruction::PUSH1}),
135135
// PUSHX plus data
136-
(m_params.isCreation ? GasCosts::txDataNonZeroGas(m_params.evmVersion) : GasCosts::createDataGas) + dataGas(util::toCompactBigEndian(m_value, 1)),
136+
(m_params.isCreation ? GasCosts::txDataNonZeroGas(m_params.evmVersion) : GasCosts::createDataGas) + dataGas(toCompactBigEndian(m_value, 1)),
137137
0
138138
);
139139
}
@@ -146,13 +146,13 @@ bigint CodeCopyMethod::gasNeeded() const
146146
// Data gas for copy routines: Some bytes are zero, but we ignore them.
147147
bytesRequired(copyRoutine()) * (m_params.isCreation ? GasCosts::txDataNonZeroGas(m_params.evmVersion) : GasCosts::createDataGas),
148148
// Data gas for data itself
149-
dataGas(util::toBigEndian(m_value))
149+
dataGas(toBigEndian(m_value))
150150
);
151151
}
152152

153153
AssemblyItems CodeCopyMethod::execute(Assembly& _assembly) const
154154
{
155-
bytes data = util::toBigEndian(m_value);
155+
bytes data = toBigEndian(m_value);
156156
assertThrow(data.size() == 32, OptimizerException, "Invalid number encoding.");
157157
AssemblyItems actualCopyRoutine = copyRoutine();
158158
actualCopyRoutine[4] = _assembly.newData(data);
@@ -192,7 +192,7 @@ AssemblyItems ComputeMethod::findRepresentation(u256 const& _value)
192192
if (_value < 0x10000)
193193
// Very small value, not worth computing
194194
return AssemblyItems{_value};
195-
else if (util::bytesRequired(~_value) < util::bytesRequired(_value))
195+
else if (numberEncodingSize(~_value) < numberEncodingSize(_value))
196196
// Negated is shorter to represent
197197
return findRepresentation(~_value) + AssemblyItems{Instruction::NOT};
198198
else

libevmasm/ControlFlowGraph.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424

2525
#pragma once
2626

27-
#include <vector>
28-
#include <memory>
2927
#include <libsolutil/Common.h>
3028
#include <libsolutil/Assertions.h>
3129
#include <libevmasm/ExpressionClasses.h>
3230

31+
#include <vector>
32+
#include <memory>
33+
#include <limits>
34+
3335
namespace solidity::evmasm
3436
{
3537

libevmasm/ExpressionClasses.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#include <functional>
3131
#include <tuple>
32+
#include <limits>
3233

3334
using namespace std;
3435
using namespace solidity;

0 commit comments

Comments
 (0)