Skip to content

Commit 1c58b91

Browse files
committed
Merge branch 'develop' of github.com:tfire/solidity into fix/remove-namespace-ast-annotations
2 parents 1653b6c + 4263b89 commit 1c58b91

File tree

190 files changed

+1682
-554
lines changed

Some content is hidden

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

190 files changed

+1682
-554
lines changed

.circleci/config.yml

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -504,28 +504,14 @@ defaults:
504504
binary_type: solcjs
505505
compile_only: 1
506506
nodejs_version: '14'
507-
- job_native_compile_ext_gnosis: &job_native_compile_ext_gnosis
508-
<<: *workflow_ubuntu2004_static
509-
name: t_native_compile_ext_gnosis
510-
project: gnosis
511-
binary_type: native
512-
compile_only: 1
513-
nodejs_version: '14'
514507

515508
- job_native_test_ext_gnosis: &job_native_test_ext_gnosis
516-
<<: *workflow_emscripten
509+
<<: *workflow_ubuntu2004_static
517510
name: t_native_test_ext_gnosis
518511
project: gnosis
519512
binary_type: native
520-
# NOTE: Tests do not start on node.js 14 ("ganache-cli exited early with code 1").
521-
nodejs_version: '12'
522-
- job_native_test_ext_gnosis_v2: &job_native_test_ext_gnosis_v2
523-
<<: *workflow_ubuntu2004_static
524-
name: t_native_test_ext_gnosis_v2
525-
project: gnosis-v2
526-
binary_type: native
527-
# NOTE: Tests do not start on node.js 14 ("ganache-cli exited early with code 1").
528-
nodejs_version: '12'
513+
# NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported"
514+
nodejs_version: '16'
529515
- job_native_test_ext_zeppelin: &job_native_test_ext_zeppelin
530516
<<: *workflow_ubuntu2004_static
531517
name: t_native_test_ext_zeppelin
@@ -1466,12 +1452,8 @@ workflows:
14661452
- t_ems_ext_hardhat: *workflow_emscripten
14671453

14681454
- t_ems_ext: *job_ems_compile_ext_colony
1469-
- t_ems_ext: *job_native_compile_ext_gnosis
14701455

1471-
# FIXME: Gnosis tests are pretty flaky right now. They often fail on CircleCI due to random ProviderError
1472-
# and there are also other less frequent problems. See https://github.com/gnosis/safe-contracts/issues/216.
1473-
#-t_ems_ext: *job_native_test_ext_gnosis
1474-
- t_ems_ext: *job_native_test_ext_gnosis_v2
1456+
- t_ems_ext: *job_native_test_ext_gnosis
14751457
- t_ems_ext: *job_native_test_ext_zeppelin
14761458
- t_ems_ext: *job_native_test_ext_ens
14771459
- t_ems_ext: *job_native_test_ext_trident
@@ -1488,8 +1470,7 @@ workflows:
14881470
<<: *workflow_trigger_on_tags
14891471
requires:
14901472
- t_ems_compile_ext_colony
1491-
- t_native_compile_ext_gnosis
1492-
- t_native_test_ext_gnosis_v2
1473+
- t_native_test_ext_gnosis
14931474
- t_native_test_ext_zeppelin
14941475
- t_native_test_ext_ens
14951476
- t_native_test_ext_trident

Changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ Language Features:
66

77
Compiler Features:
88
* JSON-AST: Added selector field for errors and events.
9+
* Peephole Optimizer: Optimize comparisons in front of conditional jumps and conditional jumps across a single unconditional jump.
10+
* Yul Optimizer: Remove ``sstore`` and ``mstore`` operations that are never read from.
911

1012
Bugfixes:
1113
* Yul IR Code Generation: Optimize embedded creation code with correct settings. This fixes potential mismatches between the constructor code of a contract compiled in isolation and the bytecode in ``type(C).creationCode``, resp. the bytecode used for ``new C(...)``.

docs/contracts/interfaces.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Interfaces are similar to abstract contracts, but they cannot have any functions
1010
There are further restrictions:
1111

1212
- They cannot inherit from other contracts, but they can inherit from other interfaces.
13-
- All declared functions must be external.
13+
- All declared functions must be external in the interface, even if they are public in the contract.
1414
- They cannot declare a constructor.
1515
- They cannot declare state variables.
1616
- They cannot declare modifiers.

libevmasm/PeepholeOptimiser.cpp

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,65 @@ struct IsZeroIsZeroJumpI: SimplePeepholeOptimizerMethod<IsZeroIsZeroJumpI>
233233
}
234234
};
235235

236+
struct EqIsZeroJumpI: SimplePeepholeOptimizerMethod<EqIsZeroJumpI>
237+
{
238+
static size_t applySimple(
239+
AssemblyItem const& _eq,
240+
AssemblyItem const& _iszero,
241+
AssemblyItem const& _pushTag,
242+
AssemblyItem const& _jumpi,
243+
std::back_insert_iterator<AssemblyItems> _out
244+
)
245+
{
246+
if (
247+
_eq == Instruction::EQ &&
248+
_iszero == Instruction::ISZERO &&
249+
_pushTag.type() == PushTag &&
250+
_jumpi == Instruction::JUMPI
251+
)
252+
{
253+
*_out = AssemblyItem(Instruction::SUB, _eq.location());
254+
*_out = _pushTag;
255+
*_out = _jumpi;
256+
return true;
257+
}
258+
else
259+
return false;
260+
}
261+
};
262+
263+
// push_tag_1 jumpi push_tag_2 jump tag_1: -> iszero push_tag_2 jumpi tag_1:
264+
struct DoubleJump: SimplePeepholeOptimizerMethod<DoubleJump>
265+
{
266+
static size_t applySimple(
267+
AssemblyItem const& _pushTag1,
268+
AssemblyItem const& _jumpi,
269+
AssemblyItem const& _pushTag2,
270+
AssemblyItem const& _jump,
271+
AssemblyItem const& _tag1,
272+
std::back_insert_iterator<AssemblyItems> _out
273+
)
274+
{
275+
if (
276+
_pushTag1.type() == PushTag &&
277+
_jumpi == Instruction::JUMPI &&
278+
_pushTag2.type() == PushTag &&
279+
_jump == Instruction::JUMP &&
280+
_tag1.type() == Tag &&
281+
_pushTag1.data() == _tag1.data()
282+
)
283+
{
284+
*_out = AssemblyItem(Instruction::ISZERO, _jumpi.location());
285+
*_out = _pushTag2;
286+
*_out = _jumpi;
287+
*_out = _tag1;
288+
return true;
289+
}
290+
else
291+
return false;
292+
}
293+
};
294+
236295
struct JumpToNext: SimplePeepholeOptimizerMethod<JumpToNext>
237296
{
238297
static size_t applySimple(
@@ -372,7 +431,7 @@ bool PeepholeOptimiser::optimise()
372431
applyMethods(
373432
state,
374433
PushPop(), OpPop(), DoublePush(), DoubleSwap(), CommutativeSwap(), SwapComparison(),
375-
DupSwap(), IsZeroIsZeroJumpI(), JumpToNext(), UnreachableCode(),
434+
DupSwap(), IsZeroIsZeroJumpI(), EqIsZeroJumpI(), DoubleJump(), JumpToNext(), UnreachableCode(),
376435
TagConjunctions(), TruthyAnd(), Identity()
377436
);
378437
if (m_optimisedItems.size() < m_items.size() || (

libevmasm/SemanticInformation.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ vector<SemanticInformation::Operation> SemanticInformation::readWriteOperations(
121121
Location::Memory,
122122
Effect::Write,
123123
paramCount - 2,
124-
paramCount - 1,
124+
// Length is in paramCount - 1, but it is only a max length,
125+
// there is no guarantee that the full area is written to.
126+
{},
125127
{}
126128
});
127129
return operations;

libsolidity/ast/Types.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2341,6 +2341,11 @@ TypeResult StructType::interfaceType(bool _inLibrary) const
23412341
return *m_interfaceType_library;
23422342
}
23432343

2344+
Declaration const* StructType::typeDefinition() const
2345+
{
2346+
return &structDefinition();
2347+
}
2348+
23442349
BoolResult StructType::validForLocation(DataLocation _loc) const
23452350
{
23462351
for (auto const& member: m_struct.members())
@@ -2473,6 +2478,11 @@ Type const* EnumType::encodingType() const
24732478
return TypeProvider::uint(8);
24742479
}
24752480

2481+
Declaration const* EnumType::typeDefinition() const
2482+
{
2483+
return &enumDefinition();
2484+
}
2485+
24762486
TypeResult EnumType::unaryOperatorResult(Token _operator) const
24772487
{
24782488
return _operator == Token::Delete ? TypeProvider::emptyTuple() : nullptr;
@@ -2541,6 +2551,11 @@ Type const& UserDefinedValueType::underlyingType() const
25412551
return *type;
25422552
}
25432553

2554+
Declaration const* UserDefinedValueType::typeDefinition() const
2555+
{
2556+
return &m_definition;
2557+
}
2558+
25442559
string UserDefinedValueType::richIdentifier() const
25452560
{
25462561
return "t_userDefinedValueType" + parenthesizeIdentifier(m_definition.name()) + to_string(m_definition.id());

libsolidity/ast/Types.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,10 @@ class Type
369369
/// are returned without modification.
370370
virtual TypeResult interfaceType(bool /*_inLibrary*/) const { return nullptr; }
371371

372+
/// @returns the declaration of a user defined type (enum, struct, user defined value type).
373+
/// Returns nullptr otherwise.
374+
virtual Declaration const* typeDefinition() const { return nullptr; }
375+
372376
/// Clears all internally cached values (if any).
373377
virtual void clearCache() const;
374378

@@ -1004,6 +1008,8 @@ class StructType: public ReferenceType
10041008
Type const* encodingType() const override;
10051009
TypeResult interfaceType(bool _inLibrary) const override;
10061010

1011+
Declaration const* typeDefinition() const override;
1012+
10071013
BoolResult validForLocation(DataLocation _loc) const override;
10081014

10091015
bool recursive() const;
@@ -1069,6 +1075,8 @@ class EnumType: public Type
10691075
return _inLibrary ? this : encodingType();
10701076
}
10711077

1078+
Declaration const* typeDefinition() const override;
1079+
10721080
EnumDefinition const& enumDefinition() const { return m_enum; }
10731081
/// @returns the value that the string has in the Enum
10741082
unsigned int memberValue(ASTString const& _member) const;
@@ -1101,6 +1109,9 @@ class UserDefinedValueType: public Type
11011109
TypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }
11021110
Type const* encodingType() const override { return &underlyingType(); }
11031111
TypeResult interfaceType(bool /* _inLibrary */) const override {return &underlyingType(); }
1112+
1113+
Declaration const* typeDefinition() const override;
1114+
11041115
std::string richIdentifier() const override;
11051116
bool operator==(Type const& _other) const override;
11061117

libsolidity/interface/OptimiserSettings.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ struct OptimiserSettings
5555
"xa[rul]" // Prune a bit more in SSA
5656
"xa[r]cL" // Turn into SSA again and simplify
5757
"gvif" // Run full inliner
58-
"CTUca[r]LsTFOtfDnca[r]Iulc" // SSA plus simplify
58+
"CTUca[r]LSsTFOtfDnca[r]Iulc" // SSA plus simplify
5959
"]"
6060
"jmul[jul] VcTOcul jmul"; // Make source short and pretty
6161

libyul/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ add_library(yul
179179
optimiser/UnusedAssignEliminator.h
180180
optimiser/UnusedStoreBase.cpp
181181
optimiser/UnusedStoreBase.h
182+
optimiser/UnusedStoreEliminator.cpp
183+
optimiser/UnusedStoreEliminator.h
182184
optimiser/Rematerialiser.cpp
183185
optimiser/Rematerialiser.h
184186
optimiser/SMTSolver.cpp

libyul/optimiser/StructuralSimplifier.cpp

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,30 @@ OptionalStatements replaceConstArgSwitch(Switch& _switchStmt, u256 const& _const
5555
return optional<vector<Statement>>{vector<Statement>{}};
5656
}
5757

58+
optional<u256> hasLiteralValue(Expression const& _expression)
59+
{
60+
if (holds_alternative<Literal>(_expression))
61+
return valueOfLiteral(std::get<Literal>(_expression));
62+
else
63+
return std::optional<u256>();
64+
}
65+
66+
bool expressionAlwaysTrue(Expression const& _expression)
67+
{
68+
if (std::optional<u256> value = hasLiteralValue(_expression))
69+
return *value != 0;
70+
else
71+
return false;
72+
}
73+
74+
bool expressionAlwaysFalse(Expression const& _expression)
75+
{
76+
if (std::optional<u256> value = hasLiteralValue(_expression))
77+
return *value == 0;
78+
else
79+
return false;
80+
}
81+
5882
}
5983

6084
void StructuralSimplifier::run(OptimiserStepContext&, Block& _ast)
@@ -103,27 +127,3 @@ void StructuralSimplifier::simplify(std::vector<yul::Statement>& _statements)
103127
}
104128
);
105129
}
106-
107-
bool StructuralSimplifier::expressionAlwaysTrue(Expression const& _expression)
108-
{
109-
if (std::optional<u256> value = hasLiteralValue(_expression))
110-
return *value != 0;
111-
else
112-
return false;
113-
}
114-
115-
bool StructuralSimplifier::expressionAlwaysFalse(Expression const& _expression)
116-
{
117-
if (std::optional<u256> value = hasLiteralValue(_expression))
118-
return *value == 0;
119-
else
120-
return false;
121-
}
122-
123-
std::optional<u256> StructuralSimplifier::hasLiteralValue(Expression const& _expression) const
124-
{
125-
if (holds_alternative<Literal>(_expression))
126-
return valueOfLiteral(std::get<Literal>(_expression));
127-
else
128-
return std::optional<u256>();
129-
}

0 commit comments

Comments
 (0)