diff --git a/CMakeLists.txt b/CMakeLists.txt index dba182345..008f458ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ include(EthPolicy) eth_policy() # project name and version should be set after cmake_policy CMP0048 -set(PROJECT_VERSION "0.6.5") +set(PROJECT_VERSION "0.6.6") # OSX target needed in order to support std::visit set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14") project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX) diff --git a/Changelog.md b/Changelog.md index 17d4fd0ae..1c0952f19 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,16 @@ +### 0.6.6 (2020-04-09) + +Important Bugfixes: + * Fix tuple assignments with components occupying multiple stack slots and different stack size on left- and right-hand-side. + + +Bugfixes: + * AST export: Export `immutable` property in the field `mutability`. + * SMTChecker: Fix internal error in the CHC engine when calling inherited functions internally. + * Type Checker: Error when trying to encode functions with call options gas and value set. + + + ### 0.6.5 (2020-04-06) Important Bugfixes: diff --git a/docs/bugs.json b/docs/bugs.json index 066e17e93..42a5277b1 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -1,4 +1,12 @@ [ + { + "name": "TupleAssignmentMultiStackSlotComponents", + "summary": "Tuple assignments with components that occupy several stack slots, i.e. nested tuples, pointers to external functions or references to dynamically sized calldata arrays, can result in invalid values.", + "description": "Tuple assignments did not correctly account for tuple components that occupy multiple stack slots in case the number of stack slots differs between left-hand-side and right-hand-side. This can either happen in the presence of nested tuples or if the right-hand-side contains external function pointers or references to dynamic calldata arrays, while the left-hand-side contains an omission.", + "introduced": "0.1.6", + "fixed": "0.6.6", + "severity": "very low" + }, { "name": "MemoryArrayCreationOverflow", "summary": "The creation of very large memory arrays can result in overlapping memory regions and thus memory corruption.", diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index b12393016..7ccd0c66a 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -111,6 +111,7 @@ }, "0.1.6": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "ExpExponentCleanup", "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", @@ -131,6 +132,7 @@ }, "0.1.7": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "ExpExponentCleanup", "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", @@ -151,6 +153,7 @@ }, "0.2.0": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "ExpExponentCleanup", "NestedArrayFunctionCallDecoder", @@ -172,6 +175,7 @@ }, "0.2.1": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "ExpExponentCleanup", "NestedArrayFunctionCallDecoder", @@ -193,6 +197,7 @@ }, "0.2.2": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "ExpExponentCleanup", "NestedArrayFunctionCallDecoder", @@ -214,6 +219,7 @@ }, "0.3.0": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "IncorrectEventSignatureInLibraries_0.4.x", @@ -237,6 +243,7 @@ }, "0.3.1": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "IncorrectEventSignatureInLibraries_0.4.x", @@ -259,6 +266,7 @@ }, "0.3.2": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "IncorrectEventSignatureInLibraries_0.4.x", @@ -281,6 +289,7 @@ }, "0.3.3": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "IncorrectEventSignatureInLibraries_0.4.x", @@ -302,6 +311,7 @@ }, "0.3.4": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "IncorrectEventSignatureInLibraries_0.4.x", @@ -323,6 +333,7 @@ }, "0.3.5": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "IncorrectEventSignatureInLibraries_0.4.x", @@ -344,6 +355,7 @@ }, "0.3.6": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "IncorrectEventSignatureInLibraries_0.4.x", @@ -363,6 +375,7 @@ }, "0.4.0": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "IncorrectEventSignatureInLibraries_0.4.x", @@ -382,6 +395,7 @@ }, "0.4.1": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "IncorrectEventSignatureInLibraries_0.4.x", @@ -401,6 +415,7 @@ }, "0.4.10": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -418,6 +433,7 @@ }, "0.4.11": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -434,6 +450,7 @@ }, "0.4.12": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -449,6 +466,7 @@ }, "0.4.13": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -464,6 +482,7 @@ }, "0.4.14": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -478,6 +497,7 @@ }, "0.4.15": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -491,6 +511,7 @@ }, "0.4.16": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -506,6 +527,7 @@ }, "0.4.17": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -522,6 +544,7 @@ }, "0.4.18": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -537,6 +560,7 @@ }, "0.4.19": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -553,6 +577,7 @@ }, "0.4.2": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "IncorrectEventSignatureInLibraries_0.4.x", @@ -571,6 +596,7 @@ }, "0.4.20": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -587,6 +613,7 @@ }, "0.4.21": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -603,6 +630,7 @@ }, "0.4.22": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -619,6 +647,7 @@ }, "0.4.23": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -634,6 +663,7 @@ }, "0.4.24": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -649,6 +679,7 @@ }, "0.4.25": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -662,6 +693,7 @@ }, "0.4.26": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -672,6 +704,7 @@ }, "0.4.3": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "IncorrectEventSignatureInLibraries_0.4.x", @@ -689,6 +722,7 @@ }, "0.4.4": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "IncorrectEventSignatureInLibraries_0.4.x", @@ -705,6 +739,7 @@ }, "0.4.5": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "UninitializedFunctionPointerInConstructor_0.4.x", @@ -723,6 +758,7 @@ }, "0.4.6": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "UninitializedFunctionPointerInConstructor_0.4.x", @@ -740,6 +776,7 @@ }, "0.4.7": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -757,6 +794,7 @@ }, "0.4.8": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -774,6 +812,7 @@ }, "0.4.9": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -791,6 +830,7 @@ }, "0.5.0": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -804,6 +844,7 @@ }, "0.5.1": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -817,6 +858,7 @@ }, "0.5.10": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "YulOptimizerRedundantAssignmentBreakContinue0.5", @@ -826,6 +868,7 @@ }, "0.5.11": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "YulOptimizerRedundantAssignmentBreakContinue0.5" @@ -834,6 +877,7 @@ }, "0.5.12": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "YulOptimizerRedundantAssignmentBreakContinue0.5" @@ -842,6 +886,7 @@ }, "0.5.13": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "YulOptimizerRedundantAssignmentBreakContinue0.5" @@ -850,6 +895,7 @@ }, "0.5.14": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "YulOptimizerRedundantAssignmentBreakContinue0.5", @@ -859,6 +905,7 @@ }, "0.5.15": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "YulOptimizerRedundantAssignmentBreakContinue0.5" @@ -867,6 +914,7 @@ }, "0.5.16": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden" ], @@ -874,12 +922,14 @@ }, "0.5.17": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow" ], "released": "2020-03-17" }, "0.5.2": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -893,6 +943,7 @@ }, "0.5.3": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -906,6 +957,7 @@ }, "0.5.4": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -919,6 +971,7 @@ }, "0.5.5": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "SignedArrayStorageCopy", @@ -934,6 +987,7 @@ }, "0.5.6": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers", @@ -949,6 +1003,7 @@ }, "0.5.7": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers", @@ -962,6 +1017,7 @@ }, "0.5.8": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "YulOptimizerRedundantAssignmentBreakContinue0.5", @@ -974,6 +1030,7 @@ }, "0.5.9": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "privateCanBeOverridden", "YulOptimizerRedundantAssignmentBreakContinue0.5", @@ -985,6 +1042,7 @@ }, "0.6.0": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow", "YulOptimizerRedundantAssignmentBreakContinue" ], @@ -992,30 +1050,40 @@ }, "0.6.1": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow" ], "released": "2020-01-02" }, "0.6.2": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow" ], "released": "2020-01-27" }, "0.6.3": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow" ], "released": "2020-02-18" }, "0.6.4": { "bugs": [ + "TupleAssignmentMultiStackSlotComponents", "MemoryArrayCreationOverflow" ], "released": "2020-03-10" }, "0.6.5": { - "bugs": [], + "bugs": [ + "TupleAssignmentMultiStackSlotComponents" + ], "released": "2020-04-06" + }, + "0.6.6": { + "bugs": [], + "released": "2020-04-09" } } \ No newline at end of file diff --git a/docs/examples/micropayment.rst b/docs/examples/micropayment.rst index cd4084c84..b4f1f6c6b 100644 --- a/docs/examples/micropayment.rst +++ b/docs/examples/micropayment.rst @@ -433,7 +433,7 @@ The full contract .. note:: The function ``splitSignature`` does not use all security checks. A real implementation should use a more rigorously tested library, - such as openzepplin's `version `_ of this code. + such as openzepplin's `version `_ of this code. Verifying Payments ------------------ diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index c7a517a0b..efb553e1a 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -106,6 +106,8 @@ set(sources formal/Sorts.h formal/SSAVariable.cpp formal/SSAVariable.h + formal/SymbolicState.cpp + formal/SymbolicState.h formal/SymbolicTypes.cpp formal/SymbolicTypes.h formal/SymbolicVariables.cpp diff --git a/libsolidity/analysis/ConstantEvaluator.h b/libsolidity/analysis/ConstantEvaluator.h index 0f2dd558e..e92113bb8 100644 --- a/libsolidity/analysis/ConstantEvaluator.h +++ b/libsolidity/analysis/ConstantEvaluator.h @@ -54,11 +54,11 @@ public: TypePointer evaluate(Expression const& _expr); private: - virtual void endVisit(BinaryOperation const& _operation); - virtual void endVisit(UnaryOperation const& _operation); - virtual void endVisit(Literal const& _literal); - virtual void endVisit(Identifier const& _identifier); - virtual void endVisit(TupleExpression const& _tuple); + void endVisit(BinaryOperation const& _operation) override; + void endVisit(UnaryOperation const& _operation) override; + void endVisit(Literal const& _literal) override; + void endVisit(Identifier const& _identifier) override; + void endVisit(TupleExpression const& _tuple) override; void setType(ASTNode const& _node, TypePointer const& _type); TypePointer type(ASTNode const& _node); diff --git a/libsolidity/analysis/StaticAnalyzer.h b/libsolidity/analysis/StaticAnalyzer.h index f3ed30b20..57ac54fb1 100644 --- a/libsolidity/analysis/StaticAnalyzer.h +++ b/libsolidity/analysis/StaticAnalyzer.h @@ -50,7 +50,7 @@ class StaticAnalyzer: private ASTConstVisitor public: /// @param _errorReporter provides the error logging functionality. explicit StaticAnalyzer(langutil::ErrorReporter& _errorReporter); - ~StaticAnalyzer(); + ~StaticAnalyzer() override; /// Performs static analysis on the given source unit and all of its sub-nodes. /// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 2bdc706a2..b2e49b052 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1430,41 +1430,37 @@ bool TypeChecker::visit(TupleExpression const& _tuple) { if (!components[i]) m_errorReporter.fatalTypeError(_tuple.location(), "Tuple component cannot be empty."); - else if (components[i]) - { - components[i]->accept(*this); - types.push_back(type(*components[i])); - if (types[i]->category() == Type::Category::Tuple) - if (dynamic_cast(*types[i]).components().empty()) - { - if (_tuple.isInlineArray()) - m_errorReporter.fatalTypeError(components[i]->location(), "Array component cannot be empty."); - m_errorReporter.typeError(components[i]->location(), "Tuple component cannot be empty."); - } + components[i]->accept(*this); + types.push_back(type(*components[i])); - // Note: code generation will visit each of the expression even if they are not assigned from. - if (types[i]->category() == Type::Category::RationalNumber && components.size() > 1) - if (!dynamic_cast(*types[i]).mobileType()) - m_errorReporter.fatalTypeError(components[i]->location(), "Invalid rational number."); - - if (_tuple.isInlineArray()) + if (types[i]->category() == Type::Category::Tuple) + if (dynamic_cast(*types[i]).components().empty()) { - solAssert(!!types[i], "Inline array cannot have empty components"); - - if ((i == 0 || inlineArrayType) && !types[i]->mobileType()) - m_errorReporter.fatalTypeError(components[i]->location(), "Invalid mobile type."); - - if (i == 0) - inlineArrayType = types[i]->mobileType(); - else if (inlineArrayType) - inlineArrayType = Type::commonType(inlineArrayType, types[i]); + if (_tuple.isInlineArray()) + m_errorReporter.fatalTypeError(components[i]->location(), "Array component cannot be empty."); + m_errorReporter.typeError(components[i]->location(), "Tuple component cannot be empty."); } - if (!components[i]->annotation().isPure) - isPure = false; + + // Note: code generation will visit each of the expression even if they are not assigned from. + if (types[i]->category() == Type::Category::RationalNumber && components.size() > 1) + if (!dynamic_cast(*types[i]).mobileType()) + m_errorReporter.fatalTypeError(components[i]->location(), "Invalid rational number."); + + if (_tuple.isInlineArray()) + { + solAssert(!!types[i], "Inline array cannot have empty components"); + + if ((i == 0 || inlineArrayType) && !types[i]->mobileType()) + m_errorReporter.fatalTypeError(components[i]->location(), "Invalid mobile type."); + + if (i == 0) + inlineArrayType = types[i]->mobileType(); + else if (inlineArrayType) + inlineArrayType = Type::commonType(inlineArrayType, types[i]); } - else - types.push_back(TypePointer()); + if (!components[i]->annotation().isPure) + isPure = false; } _tuple.annotation().isPure = isPure; if (_tuple.isInlineArray()) diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index b711758d6..d9425937f 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -217,6 +217,37 @@ ContractDefinitionAnnotation& ContractDefinition::annotation() const return initAnnotation(); } +ContractDefinition const* ContractDefinition::superContract(ContractDefinition const& _mostDerivedContract) const +{ + auto const& hierarchy = _mostDerivedContract.annotation().linearizedBaseContracts; + auto it = find(hierarchy.begin(), hierarchy.end(), this); + solAssert(it != hierarchy.end(), "Base not found in inheritance hierarchy."); + ++it; + if (it == hierarchy.end()) + return nullptr; + else + { + solAssert(*it != this, ""); + return *it; + } +} + +FunctionDefinition const* ContractDefinition::nextConstructor(ContractDefinition const& _mostDerivedContract) const +{ + ContractDefinition const* next = superContract(_mostDerivedContract); + if (next == nullptr) + return nullptr; + for (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts) + if (c == next || next == nullptr) + { + if (c->constructor()) + return c->constructor(); + next = nullptr; + } + + return nullptr; +} + TypeNameAnnotation& TypeName::annotation() const { return initAnnotation(); diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 4979d5d4e..c0f7e6dc9 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -518,6 +518,10 @@ public: bool abstract() const { return m_abstract; } + ContractDefinition const* superContract(ContractDefinition const& _mostDerivedContract) const; + /// @returns the next constructor in the inheritance hierarchy. + FunctionDefinition const* nextConstructor(ContractDefinition const& _mostDerivedContract) const; + private: std::vector> m_baseContracts; std::vector> m_subNodes; @@ -850,7 +854,17 @@ class VariableDeclaration: public Declaration { public: enum Location { Unspecified, Storage, Memory, CallData }; - enum class Constantness { Mutable, Immutable, Constant }; + enum class Mutability { Mutable, Immutable, Constant }; + static std::string mutabilityToString(Mutability _mutability) + { + switch (_mutability) + { + case Mutability::Mutable: return "mutable"; + case Mutability::Immutable: return "immutable"; + case Mutability::Constant: return "constant"; + } + return {}; + } VariableDeclaration( int64_t _id, @@ -861,7 +875,7 @@ public: Visibility _visibility, bool _isStateVar = false, bool _isIndexed = false, - Constantness _constantness = Constantness::Mutable, + Mutability _mutability = Mutability::Mutable, ASTPointer const& _overrides = nullptr, Location _referenceLocation = Location::Unspecified ): @@ -870,7 +884,7 @@ public: m_value(_value), m_isStateVariable(_isStateVar), m_isIndexed(_isIndexed), - m_constantness(_constantness), + m_mutability(_mutability), m_overrides(_overrides), m_location(_referenceLocation) {} @@ -914,8 +928,9 @@ public: bool hasReferenceOrMappingType() const; bool isStateVariable() const { return m_isStateVariable; } bool isIndexed() const { return m_isIndexed; } - bool isConstant() const { return m_constantness == Constantness::Constant; } - bool immutable() const { return m_constantness == Constantness::Immutable; } + Mutability mutability() const { return m_mutability; } + bool isConstant() const { return m_mutability == Mutability::Constant; } + bool immutable() const { return m_mutability == Mutability::Immutable; } ASTPointer const& overrides() const { return m_overrides; } Location referenceLocation() const { return m_location; } /// @returns a set of allowed storage locations for the variable. @@ -943,7 +958,7 @@ private: bool m_isStateVariable = false; ///< Whether or not this is a contract state variable bool m_isIndexed = false; ///< Whether this is an indexed variable (used by events). /// Whether the variable is "constant", "immutable" or non-marked (mutable). - Constantness m_constantness = Constantness::Mutable; + Mutability m_mutability = Mutability::Mutable; ASTPointer m_overrides; ///< Contains the override specifier node Location m_location = Location::Unspecified; ///< Location of the variable if it is of reference type. }; diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index ed3c6fff9..81802907f 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -378,6 +378,7 @@ bool ASTJsonConverter::visit(VariableDeclaration const& _node) make_pair("name", _node.name()), make_pair("typeName", toJsonOrNull(_node.typeName())), make_pair("constant", _node.isConstant()), + make_pair("mutability", VariableDeclaration::mutabilityToString(_node.mutability())), make_pair("stateVariable", _node.isStateVariable()), make_pair("storageLocation", location(_node.referenceLocation())), make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue), diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index 26a7c7b7e..7d388877b 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -411,11 +411,24 @@ ASTPointer ASTJsonImporter::createVariableDeclaration(Json: { astAssert(_node["name"].isString(), "Expected 'name' to be a string!"); - VariableDeclaration::Constantness constantness{}; - if (memberAsBool(_node, "constant")) - constantness = VariableDeclaration::Constantness::Constant; + VariableDeclaration::Mutability mutability{}; + astAssert(member(_node, "mutability").isString(), "'mutability' expected to be string."); + string const mutabilityStr = member(_node, "mutability").asString(); + if (mutabilityStr == "constant") + { + mutability = VariableDeclaration::Mutability::Constant; + astAssert(memberAsBool(_node, "constant"), ""); + } else - constantness = VariableDeclaration::Constantness::Mutable; + { + astAssert(!memberAsBool(_node, "constant"), ""); + if (mutabilityStr == "mutable") + mutability = VariableDeclaration::Mutability::Mutable; + else if (mutabilityStr == "immutable") + mutability = VariableDeclaration::Mutability::Immutable; + else + astAssert(false, ""); + } return createASTNode( _node, @@ -425,7 +438,7 @@ ASTPointer ASTJsonImporter::createVariableDeclaration(Json: visibility(_node), memberAsBool(_node, "stateVariable"), _node.isMember("indexed") ? memberAsBool(_node, "indexed") : false, - constantness, + mutability, _node["overrides"].isNull() ? nullptr : createOverrideSpecifier(member(_node, "overrides")), location(_node) ); @@ -495,7 +508,7 @@ ASTPointer ASTJsonImporter::createUserDefinedTypeName(Json: string nameString = member(_node, "name").asString(); boost::algorithm::split(strs, nameString, boost::is_any_of(".")); for (string s: strs) - namePath.push_back(ASTString(s)); + namePath.emplace_back(s); return createASTNode( _node, namePath diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 3fc649caf..2238e86f3 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -3112,6 +3112,8 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const* _sco TypePointer FunctionType::encodingType() const { + if (m_gasSet || m_valueSet) + return nullptr; // Only external functions can be encoded, internal functions cannot leave code boundaries. if (m_kind == Kind::External) return this; diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index 5cca1c1e4..8909651be 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -843,7 +843,7 @@ string ABIFunctions::abiEncodingFunctionStruct( if (dynamicMember) solAssert(dynamic, ""); - members.push_back({}); + members.emplace_back(); members.back()["preprocess"] = ""; switch (_from.location()) @@ -1336,7 +1336,7 @@ string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fr memberTempl("memoryOffset", toCompactHexWithPrefix(_type.memoryOffsetOfMember(member.name))); memberTempl("abiDecode", abiDecodingFunction(*member.type, _fromMemory, false)); - members.push_back({}); + members.emplace_back(); members.back()["decode"] = memberTempl.render(); members.back()["memberName"] = member.name; headPos += decodingType->calldataHeadSize(); diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 06080afbd..2b4a888ee 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -269,29 +269,11 @@ evmasm::AssemblyItem CompilerContext::functionEntryLabelIfExists(Declaration con FunctionDefinition const& CompilerContext::superFunction(FunctionDefinition const& _function, ContractDefinition const& _base) { solAssert(m_mostDerivedContract, "No most derived contract set."); - ContractDefinition const* super = superContract(_base); + ContractDefinition const* super = _base.superContract(mostDerivedContract()); solAssert(super, "Super contract not available."); return _function.resolveVirtual(mostDerivedContract(), super); } -FunctionDefinition const* CompilerContext::nextConstructor(ContractDefinition const& _contract) const -{ - ContractDefinition const* next = superContract(_contract); - if (next == nullptr) - return nullptr; - for (ContractDefinition const* c: m_mostDerivedContract->annotation().linearizedBaseContracts) - if (next != nullptr && next != c) - continue; - else - { - next = nullptr; - if (c->constructor()) - return c->constructor(); - } - - return nullptr; -} - ContractDefinition const& CompilerContext::mostDerivedContract() const { solAssert(m_mostDerivedContract, "Most derived contract not set."); @@ -536,21 +518,6 @@ LinkerObject const& CompilerContext::assembledObject() const return object; } -ContractDefinition const* CompilerContext::superContract(ContractDefinition const& _contract) const -{ - auto const& hierarchy = mostDerivedContract().annotation().linearizedBaseContracts; - auto it = find(hierarchy.begin(), hierarchy.end(), &_contract); - solAssert(it != hierarchy.end(), "Base not found in inheritance hierarchy."); - ++it; - if (it == hierarchy.end()) - return nullptr; - else - { - solAssert(*it != &_contract, ""); - return *it; - } -} - string CompilerContext::revertReasonIfDebug(string const& _message) { return YulUtilFunctions::revertReasonIfDebug(m_revertStrings, _message); diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index a8e494435..0720a8f3b 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -117,8 +117,6 @@ public: /// @returns the function that overrides the given declaration from the most derived class just /// above _base in the current inheritance hierarchy. FunctionDefinition const& superFunction(FunctionDefinition const& _function, ContractDefinition const& _base); - /// @returns the next constructor in the inheritance hierarchy. - FunctionDefinition const* nextConstructor(ContractDefinition const& _contract) const; /// Sets the contract currently being compiled - the most derived one. void setMostDerivedContract(ContractDefinition const& _contract) { m_mostDerivedContract = &_contract; } ContractDefinition const& mostDerivedContract() const; @@ -313,8 +311,6 @@ public: RevertStrings revertStrings() const { return m_revertStrings; } private: - /// @returns a pointer to the contract directly above the given contract. - ContractDefinition const* superContract(ContractDefinition const& _contract) const; /// Updates source location set in the assembly. void updateSourceLocation(); diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index d4f35ad79..3d0117707 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -1108,12 +1108,12 @@ void CompilerUtils::convertType( // Value shrank for (unsigned j = targetSize; j < sourceSize; ++j) { - moveToStackTop(depth - 1, 1); + moveToStackTop(depth + targetSize - sourceSize, 1); m_context << Instruction::POP; } // Value grew if (targetSize > sourceSize) - moveIntoStack(depth + targetSize - sourceSize - 1, targetSize - sourceSize); + moveIntoStack(depth - sourceSize, targetSize - sourceSize); } } depth -= sourceSize; diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 822ce3b66..a599de6a4 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -159,7 +159,7 @@ void ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _c if (FunctionDefinition const* constructor = _contract.constructor()) appendConstructor(*constructor); - else if (auto c = m_context.nextConstructor(_contract)) + else if (auto c = _contract.nextConstructor(m_context.mostDerivedContract())) appendBaseConstructor(*c); else appendCallValueCheck(); @@ -596,7 +596,9 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) appendStackVariableInitialisation(*variable); if (_function.isConstructor()) - if (auto c = m_context.nextConstructor(dynamic_cast(*_function.scope()))) + if (auto c = dynamic_cast(*_function.scope()).nextConstructor( + m_context.mostDerivedContract() + )) appendBaseConstructor(*c); solAssert(m_returnTags.empty(), ""); diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 5ae4b71d7..6d8d15f61 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -352,7 +352,7 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract) vector> functions; for (auto const& function: _contract.interfaceFunctions()) { - functions.push_back({}); + functions.emplace_back(); map& templ = functions.back(); templ["functionSelector"] = "0x" + function.first.hex(); FunctionTypePointer const& type = function.second; diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 141a3eb32..1b4e8174a 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -376,7 +377,7 @@ void BMC::endVisit(FunctionCall const& _funCall) SMTEncoder::endVisit(_funCall); auto value = _funCall.arguments().front(); solAssert(value, ""); - smt::Expression thisBalance = m_context.balance(); + smt::Expression thisBalance = m_context.state().balance(); addVerificationTarget( VerificationTarget::Type::Balance, diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index e10c16d39..5067e1396 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -961,7 +961,11 @@ smt::Expression CHC::predicate(FunctionCall const& _funCall) for (auto const& var: function->returnParameters()) args.push_back(m_context.variable(*var)->currentValue()); - return (*m_summaries.at(contract).at(function))(args); + if (contract->isLibrary()) + return (*m_summaries.at(contract).at(function))(args); + + solAssert(m_currentContract, ""); + return (*m_summaries.at(m_currentContract).at(function))(args); } void CHC::addRule(smt::Expression const& _rule, string const& _ruleName) diff --git a/libsolidity/formal/EncodingContext.cpp b/libsolidity/formal/EncodingContext.cpp index 1f7b7a5e0..3e0e4fa7e 100644 --- a/libsolidity/formal/EncodingContext.cpp +++ b/libsolidity/formal/EncodingContext.cpp @@ -25,13 +25,8 @@ using namespace solidity::util; using namespace solidity::frontend::smt; EncodingContext::EncodingContext(): - m_thisAddress(make_unique("this", *this)) + m_state(*this) { - auto sort = make_shared( - SortProvider::intSort, - SortProvider::intSort - ); - m_balances = make_unique(sort, "balances", *this); } void EncodingContext::reset() @@ -39,8 +34,7 @@ void EncodingContext::reset() resetAllVariables(); m_expressions.clear(); m_globalContext.clear(); - m_thisAddress->resetIndex(); - m_balances->resetIndex(); + m_state.reset(); m_assertions.clear(); } @@ -183,40 +177,6 @@ bool EncodingContext::knownGlobalSymbol(string const& _var) const return m_globalContext.count(_var); } -// Blockchain - -Expression EncodingContext::thisAddress() -{ - return m_thisAddress->currentValue(); -} - -Expression EncodingContext::balance() -{ - return balance(m_thisAddress->currentValue()); -} - -Expression EncodingContext::balance(Expression _address) -{ - return Expression::select(m_balances->currentValue(), move(_address)); -} - -void EncodingContext::transfer(Expression _from, Expression _to, Expression _value) -{ - unsigned indexBefore = m_balances->index(); - addBalance(_from, 0 - _value); - addBalance(_to, move(_value)); - unsigned indexAfter = m_balances->index(); - solAssert(indexAfter > indexBefore, ""); - m_balances->increaseIndex(); - /// Do not apply the transfer operation if _from == _to. - auto newBalances = Expression::ite( - move(_from) == move(_to), - m_balances->valueAtIndex(indexBefore), - m_balances->valueAtIndex(indexAfter) - ); - addAssertion(m_balances->currentValue() == newBalances); -} - /// Solver. Expression EncodingContext::assertions() @@ -232,7 +192,7 @@ void EncodingContext::pushSolver() if (m_accumulateAssertions) m_assertions.push_back(assertions()); else - m_assertions.push_back(smt::Expression(true)); + m_assertions.emplace_back(true); } void EncodingContext::popSolver() @@ -248,16 +208,3 @@ void EncodingContext::addAssertion(Expression const& _expr) else m_assertions.back() = _expr && move(m_assertions.back()); } - -/// Private helpers. - -void EncodingContext::addBalance(Expression _address, Expression _value) -{ - auto newBalances = Expression::store( - m_balances->currentValue(), - _address, - balance(_address) + move(_value) - ); - m_balances->increaseIndex(); - addAssertion(newBalances == m_balances->currentValue()); -} diff --git a/libsolidity/formal/EncodingContext.h b/libsolidity/formal/EncodingContext.h index 648f7dc33..d62de055d 100644 --- a/libsolidity/formal/EncodingContext.h +++ b/libsolidity/formal/EncodingContext.h @@ -18,6 +18,7 @@ #pragma once #include +#include #include #include @@ -121,18 +122,6 @@ public: bool knownGlobalSymbol(std::string const& _var) const; //@} - /// Blockchain. - //@{ - /// Value of `this` address. - Expression thisAddress(); - /// @returns the symbolic balance of address `this`. - Expression balance(); - /// @returns the symbolic balance of an address. - Expression balance(Expression _address); - /// Transfer _value from _from to _to. - void transfer(Expression _from, Expression _to, Expression _value); - //@} - /// Solver. //@{ /// @returns conjunction of all added assertions. @@ -148,10 +137,9 @@ public: } //@} -private: - /// Adds _value to _account's balance. - void addBalance(Expression _account, Expression _value); + SymbolicState& state() { return m_state; } +private: /// Symbolic expressions. //{@ /// Symbolic variables. @@ -164,11 +152,8 @@ private: /// variables and functions. std::unordered_map> m_globalContext; - /// Symbolic `this` address. - std::unique_ptr m_thisAddress; - - /// Symbolic balances. - std::unique_ptr m_balances; + /// Symbolic representation of the blockchain state. + SymbolicState m_state; //@} /// Solver related. diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 0efaf90a9..f02d32aae 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -619,10 +620,10 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall) auto const& value = args.front(); solAssert(value, ""); - smt::Expression thisBalance = m_context.balance(); + smt::Expression thisBalance = m_context.state().balance(); setSymbolicUnknownValue(thisBalance, TypeProvider::uint256(), m_context); - m_context.transfer(m_context.thisAddress(), expr(address), expr(*value)); + m_context.state().transfer(m_context.state().thisAddress(), expr(address), expr(*value)); break; } default: @@ -711,7 +712,7 @@ void SMTEncoder::endVisit(Identifier const& _identifier) defineGlobalVariable(_identifier.name(), _identifier); else if (_identifier.name() == "this") { - defineExpr(_identifier, m_context.thisAddress()); + defineExpr(_identifier, m_context.state().thisAddress()); m_uninterpretedTerms.insert(&_identifier); } else @@ -858,7 +859,7 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess) _memberAccess.expression().accept(*this); if (_memberAccess.memberName() == "balance") { - defineExpr(_memberAccess, m_context.balance(expr(_memberAccess.expression()))); + defineExpr(_memberAccess, m_context.state().balance(expr(_memberAccess.expression()))); setSymbolicUnknownValue(*m_context.expression(_memberAccess), m_context); m_uninterpretedTerms.insert(&_memberAccess); return false; diff --git a/libsolidity/formal/SymbolicState.cpp b/libsolidity/formal/SymbolicState.cpp new file mode 100644 index 000000000..d38e79c54 --- /dev/null +++ b/libsolidity/formal/SymbolicState.cpp @@ -0,0 +1,82 @@ +/* + 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 . +*/ + +#include + +#include + +using namespace std; +using namespace solidity::frontend::smt; + +SymbolicState::SymbolicState(EncodingContext& _context): + m_context(_context) +{ +} + +void SymbolicState::reset() +{ + m_thisAddress.resetIndex(); + m_balances.resetIndex(); +} + +// Blockchain + +Expression SymbolicState::thisAddress() +{ + return m_thisAddress.currentValue(); +} + +Expression SymbolicState::balance() +{ + return balance(m_thisAddress.currentValue()); +} + +Expression SymbolicState::balance(Expression _address) +{ + return Expression::select(m_balances.currentValue(), move(_address)); +} + +void SymbolicState::transfer(Expression _from, Expression _to, Expression _value) +{ + unsigned indexBefore = m_balances.index(); + addBalance(_from, 0 - _value); + addBalance(_to, move(_value)); + unsigned indexAfter = m_balances.index(); + solAssert(indexAfter > indexBefore, ""); + m_balances.increaseIndex(); + /// Do not apply the transfer operation if _from == _to. + auto newBalances = Expression::ite( + move(_from) == move(_to), + m_balances.valueAtIndex(indexBefore), + m_balances.valueAtIndex(indexAfter) + ); + m_context.addAssertion(m_balances.currentValue() == newBalances); +} + +/// Private helpers. + +void SymbolicState::addBalance(Expression _address, Expression _value) +{ + auto newBalances = Expression::store( + m_balances.currentValue(), + _address, + balance(_address) + move(_value) + ); + m_balances.increaseIndex(); + m_context.addAssertion(newBalances == m_balances.currentValue()); +} + diff --git a/libsolidity/formal/SymbolicState.h b/libsolidity/formal/SymbolicState.h new file mode 100644 index 000000000..380bfda51 --- /dev/null +++ b/libsolidity/formal/SymbolicState.h @@ -0,0 +1,71 @@ +/* + 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 . +*/ + +#pragma once + +#include +#include +#include + +namespace solidity::frontend::smt +{ + +class EncodingContext; + +/** + * Symbolic representation of the blockchain state. + */ +class SymbolicState +{ +public: + SymbolicState(EncodingContext& _context); + + void reset(); + + /// Blockchain. + //@{ + /// Value of `this` address. + Expression thisAddress(); + /// @returns the symbolic balance of address `this`. + Expression balance(); + /// @returns the symbolic balance of an address. + Expression balance(Expression _address); + /// Transfer _value from _from to _to. + void transfer(Expression _from, Expression _to, Expression _value); + //@} + +private: + /// Adds _value to _account's balance. + void addBalance(Expression _account, Expression _value); + + EncodingContext& m_context; + + /// Symbolic `this` address. + SymbolicAddressVariable m_thisAddress{ + "this", + m_context + }; + + /// Symbolic balances. + SymbolicArrayVariable m_balances{ + std::make_shared(SortProvider::intSort, SortProvider::intSort), + "balances", + m_context + }; +}; + +} diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index a97114e83..fc2b51300 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -200,7 +200,7 @@ bool isArtifactRequested(Json::Value const& _outputSelection, string const& _fil /// for Contract-level targets try both contract name and wildcard vector contracts{ _contract }; if (!_contract.empty()) - contracts.push_back("*"); + contracts.emplace_back("*"); for (auto const& contract: contracts) if ( _outputSelection[file].isMember(contract) && diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 2f23c8c22..befd3c696 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -695,7 +695,7 @@ ASTPointer Parser::parseVariableDeclaration( ); bool isIndexed = false; - VariableDeclaration::Constantness constantness = VariableDeclaration::Constantness::Mutable; + VariableDeclaration::Mutability mutability = VariableDeclaration::Mutability::Mutable; ASTPointer overrides = nullptr; Visibility visibility(Visibility::Default); VariableDeclaration::Location location = VariableDeclaration::Location::Unspecified; @@ -732,15 +732,15 @@ ASTPointer Parser::parseVariableDeclaration( isIndexed = true; else if (token == Token::Constant || token == Token::Immutable) { - if (constantness != VariableDeclaration::Constantness::Mutable) + if (mutability != VariableDeclaration::Mutability::Mutable) parserError( - string("Constantness already set to ") + - (constantness == VariableDeclaration::Constantness::Constant ? "\"constant\"" : "\"immutable\"") + string("Mutability already set to ") + + (mutability == VariableDeclaration::Mutability::Constant ? "\"constant\"" : "\"immutable\"") ); else if (token == Token::Constant) - constantness = VariableDeclaration::Constantness::Constant; + mutability = VariableDeclaration::Mutability::Constant; else if (token == Token::Immutable) - constantness = VariableDeclaration::Constantness::Immutable; + mutability = VariableDeclaration::Mutability::Immutable; } else if (_options.allowLocationSpecifier && TokenTraits::isLocationSpecifier(token)) { @@ -800,7 +800,7 @@ ASTPointer Parser::parseVariableDeclaration( visibility, _options.isStateVariable, isIndexed, - constantness, + mutability, overrides, location ); diff --git a/libsolutil/CommonData.h b/libsolutil/CommonData.h index f969ad212..feed0925f 100644 --- a/libsolutil/CommonData.h +++ b/libsolutil/CommonData.h @@ -38,7 +38,7 @@ /// Operators need to stay in the global namespace. /// Concatenate the contents of a container onto a vector -template std::vector& operator+=(std::vector& _a, U const& _b) +template std::vector& operator+=(std::vector& _a, U& _b) { for (auto const& i: _b) _a.push_back(i); @@ -51,7 +51,7 @@ template std::vector& operator+=(std::vector& _a, U&& _ return _a; } /// Concatenate the contents of a container onto a multiset -template std::multiset& operator+=(std::multiset& _a, U const& _b) +template std::multiset& operator+=(std::multiset& _a, U& _b) { _a.insert(_b.begin(), _b.end()); return _a; @@ -64,7 +64,7 @@ template std::multiset& operator+=(std::multiset std::set& operator+=(std::set& _a, U const& _b) +template std::set& operator+=(std::set& _a, U& _b) { _a.insert(_b.begin(), _b.end()); return _a; diff --git a/libyul/backends/evm/EVMAssembly.h b/libyul/backends/evm/EVMAssembly.h index e4ba4979a..744d8738b 100644 --- a/libyul/backends/evm/EVMAssembly.h +++ b/libyul/backends/evm/EVMAssembly.h @@ -38,7 +38,7 @@ class EVMAssembly: public AbstractAssembly { public: explicit EVMAssembly(bool _evm15 = false): m_evm15(_evm15) { } - virtual ~EVMAssembly() = default; + ~EVMAssembly() override = default; /// Set a new source location valid starting from the next instruction. void setSourceLocation(langutil::SourceLocation const& _location) override; diff --git a/libyul/backends/evm/EVMCodeTransform.h b/libyul/backends/evm/EVMCodeTransform.h index fb4bc38e1..eae870815 100644 --- a/libyul/backends/evm/EVMCodeTransform.h +++ b/libyul/backends/evm/EVMCodeTransform.h @@ -92,10 +92,10 @@ public: {} public: - void operator()(Identifier const& _identifier); - void operator()(FunctionDefinition const&); - void operator()(ForLoop const&); - void operator()(Block const& _block); + void operator()(Identifier const& _identifier) override; + void operator()(FunctionDefinition const&) override; + void operator()(ForLoop const&) override; + void operator()(Block const& _block) override; private: void increaseRefIfFound(YulString _variableName); diff --git a/libyul/backends/evm/NoOutputAssembly.h b/libyul/backends/evm/NoOutputAssembly.h index bc914f9ac..d72f9ea66 100644 --- a/libyul/backends/evm/NoOutputAssembly.h +++ b/libyul/backends/evm/NoOutputAssembly.h @@ -45,7 +45,7 @@ class NoOutputAssembly: public AbstractAssembly { public: explicit NoOutputAssembly(bool _evm15 = false): m_evm15(_evm15) { } - virtual ~NoOutputAssembly() = default; + ~NoOutputAssembly() override = default; void setSourceLocation(langutil::SourceLocation const&) override {} int stackHeight() const override { return m_stackHeight; } diff --git a/libyul/backends/wasm/WordSizeTransform.cpp b/libyul/backends/wasm/WordSizeTransform.cpp index eec04fae6..4046f82bd 100644 --- a/libyul/backends/wasm/WordSizeTransform.cpp +++ b/libyul/backends/wasm/WordSizeTransform.cpp @@ -104,7 +104,7 @@ void WordSizeTransform::operator()(Block& _block) auto newLhs = generateU64IdentifierNames(varDecl.variables[0].name); vector ret; for (int i = 0; i < 3; i++) - ret.push_back(VariableDeclaration{ + ret.emplace_back(VariableDeclaration{ varDecl.location, {TypedName{varDecl.location, newLhs[i], m_targetDialect.defaultType}}, make_unique(Literal{ @@ -114,7 +114,7 @@ void WordSizeTransform::operator()(Block& _block) m_targetDialect.defaultType }) }); - ret.push_back(VariableDeclaration{ + ret.emplace_back(VariableDeclaration{ varDecl.location, {TypedName{varDecl.location, newLhs[3], m_targetDialect.defaultType}}, std::move(varDecl.value) @@ -135,8 +135,7 @@ void WordSizeTransform::operator()(Block& _block) auto newLhs = generateU64IdentifierNames(varDecl.variables[0].name); vector ret; for (int i = 0; i < 4; i++) - ret.push_back( - VariableDeclaration{ + ret.emplace_back(VariableDeclaration{ varDecl.location, {TypedName{varDecl.location, newLhs[i], m_targetDialect.defaultType}}, std::move(newRhs[i]) @@ -165,7 +164,7 @@ void WordSizeTransform::operator()(Block& _block) auto newLhs = generateU64IdentifierNames(assignment.variableNames[0].name); vector ret; for (int i = 0; i < 3; i++) - ret.push_back(Assignment{ + ret.emplace_back(Assignment{ assignment.location, {Identifier{assignment.location, newLhs[i]}}, make_unique(Literal{ @@ -175,7 +174,7 @@ void WordSizeTransform::operator()(Block& _block) m_targetDialect.defaultType }) }); - ret.push_back(Assignment{ + ret.emplace_back(Assignment{ assignment.location, {Identifier{assignment.location, newLhs[3]}}, std::move(assignment.value) @@ -196,8 +195,7 @@ void WordSizeTransform::operator()(Block& _block) YulString lhsName = assignment.variableNames[0].name; vector ret; for (int i = 0; i < 4; i++) - ret.push_back( - Assignment{ + ret.emplace_back(Assignment{ assignment.location, {Identifier{assignment.location, m_variableMapping.at(lhsName)[i]}}, std::move(newRhs[i]) diff --git a/libyul/optimiser/ASTCopier.h b/libyul/optimiser/ASTCopier.h index 0ac0b5f82..3a05d2ca3 100644 --- a/libyul/optimiser/ASTCopier.h +++ b/libyul/optimiser/ASTCopier.h @@ -65,7 +65,7 @@ public: class ASTCopier: public ExpressionCopier, public StatementCopier { public: - virtual ~ASTCopier() = default; + ~ASTCopier() override = default; Expression operator()(Literal const& _literal) override; Expression operator()(Identifier const& _identifier) override; Expression operator()(FunctionCall const&) override; diff --git a/libyul/optimiser/ExpressionSimplifier.h b/libyul/optimiser/ExpressionSimplifier.h index c11ab9bf3..ce83b4e1e 100644 --- a/libyul/optimiser/ExpressionSimplifier.h +++ b/libyul/optimiser/ExpressionSimplifier.h @@ -46,7 +46,7 @@ public: static void run(OptimiserStepContext&, Block& _ast); using ASTModifier::operator(); - virtual void visit(Expression& _expression); + void visit(Expression& _expression) override; private: explicit ExpressionSimplifier(Dialect const& _dialect): DataFlowAnalyzer(_dialect) {} diff --git a/libyul/optimiser/FunctionHoister.h b/libyul/optimiser/FunctionHoister.h index 2a88e1acf..7106c03a4 100644 --- a/libyul/optimiser/FunctionHoister.h +++ b/libyul/optimiser/FunctionHoister.h @@ -42,7 +42,7 @@ public: static void run(OptimiserStepContext&, Block& _ast) { FunctionHoister{}(_ast); } using ASTModifier::operator(); - virtual void operator()(Block& _block); + void operator()(Block& _block) override; private: FunctionHoister() = default; diff --git a/libyul/optimiser/NameCollector.cpp b/libyul/optimiser/NameCollector.cpp index 33a5b624a..f9bb40bf4 100644 --- a/libyul/optimiser/NameCollector.cpp +++ b/libyul/optimiser/NameCollector.cpp @@ -36,9 +36,9 @@ void NameCollector::operator()(VariableDeclaration const& _varDecl) void NameCollector::operator ()(FunctionDefinition const& _funDef) { m_names.emplace(_funDef.name); - for (auto const arg: _funDef.parameters) + for (auto const& arg: _funDef.parameters) m_names.emplace(arg.name); - for (auto const ret: _funDef.returnVariables) + for (auto const& ret: _funDef.returnVariables) m_names.emplace(ret.name); ASTWalker::operator ()(_funDef); } diff --git a/libyul/optimiser/NameCollector.h b/libyul/optimiser/NameCollector.h index 97fbd27c6..a48aa1a3b 100644 --- a/libyul/optimiser/NameCollector.h +++ b/libyul/optimiser/NameCollector.h @@ -61,8 +61,8 @@ public: {} using ASTWalker::operator (); - virtual void operator()(Identifier const& _identifier); - virtual void operator()(FunctionCall const& _funCall); + void operator()(Identifier const& _identifier) override; + void operator()(FunctionCall const& _funCall) override; static std::map countReferences(Block const& _block, CountWhat _countWhat = VariablesAndFunctions); static std::map countReferences(FunctionDefinition const& _function, CountWhat _countWhat = VariablesAndFunctions); diff --git a/libyul/optimiser/Semantics.h b/libyul/optimiser/Semantics.h index 4efc83247..46d2984ca 100644 --- a/libyul/optimiser/Semantics.h +++ b/libyul/optimiser/Semantics.h @@ -104,7 +104,7 @@ public: static bool containsMSize(Dialect const& _dialect, Block const& _ast); using ASTWalker::operator(); - void operator()(FunctionCall const& _funCall); + void operator()(FunctionCall const& _funCall) override; private: MSizeFinder(Dialect const& _dialect): m_dialect(_dialect) {} @@ -129,7 +129,7 @@ public: } using ASTWalker::operator(); - void operator()(Leave const&) { m_leaveFound = true; } + void operator()(Leave const&) override { m_leaveFound = true; } private: LeaveFinder() = default; diff --git a/libyul/optimiser/TypeInfo.cpp b/libyul/optimiser/TypeInfo.cpp index ea2d81a83..adb6e1cce 100644 --- a/libyul/optimiser/TypeInfo.cpp +++ b/libyul/optimiser/TypeInfo.cpp @@ -50,12 +50,12 @@ public: ASTWalker::operator()(_funDef); auto& funType = functionTypes[_funDef.name]; - for (auto const arg: _funDef.parameters) + for (auto const& arg: _funDef.parameters) { funType.parameters.emplace_back(arg.type); variableTypes[arg.name] = arg.type; } - for (auto const ret: _funDef.returnVariables) + for (auto const& ret: _funDef.returnVariables) { funType.returns.emplace_back(ret.type); variableTypes[ret.name] = ret.type; diff --git a/scripts/ASTImportTest.sh b/scripts/ASTImportTest.sh index f9172df0c..b3a1b6724 100755 --- a/scripts/ASTImportTest.sh +++ b/scripts/ASTImportTest.sh @@ -4,7 +4,7 @@ # first exporting a .sol file to JSON, then loading it into the compiler # and exporting it again. The second JSON should be identical to the first -REPO_ROOT=$(realpath "$(dirname "$0")"/..) +REPO_ROOT=$(readlink -f "$(dirname "$0")"/..) SOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-build} SOLC=${REPO_ROOT}/${SOLIDITY_BUILD_DIR}/solc/solc SPLITSOURCES=${REPO_ROOT}/scripts/splitSources.py diff --git a/test/cmdlineTests/recovery_ast_constructor/output b/test/cmdlineTests/recovery_ast_constructor/output index e7dd79791..f2cc2ccf8 100644 --- a/test/cmdlineTests/recovery_ast_constructor/output +++ b/test/cmdlineTests/recovery_ast_constructor/output @@ -160,6 +160,7 @@ JSON AST: "attributes": { "constant": false, + "mutability": "mutable", "name": "", "overrides": null, "scope": 17, diff --git a/test/libsolidity/ASTJSON/address_payable.json b/test/libsolidity/ASTJSON/address_payable.json index fbf2f3e59..ef965ac79 100644 --- a/test/libsolidity/ASTJSON/address_payable.json +++ b/test/libsolidity/ASTJSON/address_payable.json @@ -31,6 +31,7 @@ "constant": false, "functionSelector": "97682884", "id": 4, + "mutability": "mutable", "name": "m", "nodeType": "VariableDeclaration", "overrides": null, @@ -100,6 +101,7 @@ { "constant": false, "id": 12, + "mutability": "mutable", "name": "a", "nodeType": "VariableDeclaration", "overrides": null, @@ -241,6 +243,7 @@ { "constant": false, "id": 22, + "mutability": "mutable", "name": "c", "nodeType": "VariableDeclaration", "overrides": null, @@ -507,6 +510,7 @@ { "constant": false, "id": 6, + "mutability": "mutable", "name": "arg", "nodeType": "VariableDeclaration", "overrides": null, @@ -547,6 +551,7 @@ { "constant": false, "id": 9, + "mutability": "mutable", "name": "r", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/address_payable_legacy.json b/test/libsolidity/ASTJSON/address_payable_legacy.json index c45e75c4a..dd33e6408 100644 --- a/test/libsolidity/ASTJSON/address_payable_legacy.json +++ b/test/libsolidity/ASTJSON/address_payable_legacy.json @@ -41,6 +41,7 @@ { "constant": false, "functionSelector": "97682884", + "mutability": "mutable", "name": "m", "overrides": null, "scope": 39, @@ -118,6 +119,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "arg", "overrides": null, "scope": 38, @@ -157,6 +159,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "r", "overrides": null, "scope": 38, @@ -206,6 +209,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "a", "overrides": null, "scope": 37, @@ -359,6 +363,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "c", "overrides": null, "scope": 37, diff --git a/test/libsolidity/ASTJSON/array_type_name.json b/test/libsolidity/ASTJSON/array_type_name.json index 6fea9f532..e97518cb8 100644 --- a/test/libsolidity/ASTJSON/array_type_name.json +++ b/test/libsolidity/ASTJSON/array_type_name.json @@ -30,6 +30,7 @@ { "constant": false, "id": 3, + "mutability": "mutable", "name": "i", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/array_type_name_legacy.json b/test/libsolidity/ASTJSON/array_type_name_legacy.json index a706c2f3a..37175bb37 100644 --- a/test/libsolidity/ASTJSON/array_type_name_legacy.json +++ b/test/libsolidity/ASTJSON/array_type_name_legacy.json @@ -40,6 +40,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "i", "overrides": null, "scope": 4, diff --git a/test/libsolidity/ASTJSON/assembly/nested_functions.json b/test/libsolidity/ASTJSON/assembly/nested_functions.json index b990a963f..73022e005 100644 --- a/test/libsolidity/ASTJSON/assembly/nested_functions.json +++ b/test/libsolidity/ASTJSON/assembly/nested_functions.json @@ -121,6 +121,7 @@ { "constant": false, "id": 3, + "mutability": "mutable", "name": "x", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/assembly/nested_functions_legacy.json b/test/libsolidity/ASTJSON/assembly/nested_functions_legacy.json index abaf60fb7..e2b4926f7 100644 --- a/test/libsolidity/ASTJSON/assembly/nested_functions_legacy.json +++ b/test/libsolidity/ASTJSON/assembly/nested_functions_legacy.json @@ -77,6 +77,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "x", "overrides": null, "scope": 7, diff --git a/test/libsolidity/ASTJSON/assembly/slot_offset.json b/test/libsolidity/ASTJSON/assembly/slot_offset.json index 68a7603ea..75c22243c 100644 --- a/test/libsolidity/ASTJSON/assembly/slot_offset.json +++ b/test/libsolidity/ASTJSON/assembly/slot_offset.json @@ -35,6 +35,7 @@ { "constant": false, "id": 2, + "mutability": "mutable", "name": "x", "nodeType": "VariableDeclaration", "overrides": null, @@ -72,6 +73,7 @@ { "constant": false, "id": 5, + "mutability": "mutable", "name": "s", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/assembly/slot_offset_legacy.json b/test/libsolidity/ASTJSON/assembly/slot_offset_legacy.json index 800e5b627..083f8dd52 100644 --- a/test/libsolidity/ASTJSON/assembly/slot_offset_legacy.json +++ b/test/libsolidity/ASTJSON/assembly/slot_offset_legacy.json @@ -50,6 +50,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "x", "overrides": null, "scope": 3, @@ -85,6 +86,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "s", "overrides": null, "scope": 11, diff --git a/test/libsolidity/ASTJSON/assembly/var_access.json b/test/libsolidity/ASTJSON/assembly/var_access.json index 1e66ef6b3..0ef180ced 100644 --- a/test/libsolidity/ASTJSON/assembly/var_access.json +++ b/test/libsolidity/ASTJSON/assembly/var_access.json @@ -45,6 +45,7 @@ { "constant": false, "id": 4, + "mutability": "mutable", "name": "x", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/assembly/var_access_legacy.json b/test/libsolidity/ASTJSON/assembly/var_access_legacy.json index 0442ace76..21cda71e8 100644 --- a/test/libsolidity/ASTJSON/assembly/var_access_legacy.json +++ b/test/libsolidity/ASTJSON/assembly/var_access_legacy.json @@ -101,6 +101,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "x", "overrides": null, "scope": 7, diff --git a/test/libsolidity/ASTJSON/function_type.json b/test/libsolidity/ASTJSON/function_type.json index 33ba4b22a..e1e83a316 100644 --- a/test/libsolidity/ASTJSON/function_type.json +++ b/test/libsolidity/ASTJSON/function_type.json @@ -53,6 +53,7 @@ { "constant": false, "id": 6, + "mutability": "mutable", "name": "x", "nodeType": "VariableDeclaration", "overrides": null, @@ -85,6 +86,7 @@ { "constant": false, "id": 3, + "mutability": "mutable", "name": "", "nodeType": "VariableDeclaration", "overrides": null, @@ -139,6 +141,7 @@ { "constant": false, "id": 13, + "mutability": "mutable", "name": "", "nodeType": "VariableDeclaration", "overrides": null, @@ -171,6 +174,7 @@ { "constant": false, "id": 10, + "mutability": "mutable", "name": "", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/function_type_legacy.json b/test/libsolidity/ASTJSON/function_type_legacy.json index 8fa58f9c9..e86eb16a6 100644 --- a/test/libsolidity/ASTJSON/function_type_legacy.json +++ b/test/libsolidity/ASTJSON/function_type_legacy.json @@ -64,6 +64,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "x", "overrides": null, "scope": 16, @@ -104,6 +105,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "", "overrides": null, "scope": 5, @@ -157,6 +159,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "", "overrides": null, "scope": 16, @@ -197,6 +200,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "", "overrides": null, "scope": 12, diff --git a/test/libsolidity/ASTJSON/global_struct.json b/test/libsolidity/ASTJSON/global_struct.json index 6eaaee8d9..64cf62a53 100644 --- a/test/libsolidity/ASTJSON/global_struct.json +++ b/test/libsolidity/ASTJSON/global_struct.json @@ -19,6 +19,7 @@ { "constant": false, "id": 2, + "mutability": "mutable", "name": "a", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/global_struct_legacy.json b/test/libsolidity/ASTJSON/global_struct_legacy.json index fd68cee57..ef0f71c37 100644 --- a/test/libsolidity/ASTJSON/global_struct_legacy.json +++ b/test/libsolidity/ASTJSON/global_struct_legacy.json @@ -26,6 +26,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "a", "overrides": null, "scope": 3, diff --git a/test/libsolidity/ASTJSON/long_type_name_binary_operation.json b/test/libsolidity/ASTJSON/long_type_name_binary_operation.json index e6d8b4d20..6e025f5f9 100644 --- a/test/libsolidity/ASTJSON/long_type_name_binary_operation.json +++ b/test/libsolidity/ASTJSON/long_type_name_binary_operation.json @@ -45,6 +45,7 @@ { "constant": false, "id": 4, + "mutability": "mutable", "name": "a", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/long_type_name_binary_operation_legacy.json b/test/libsolidity/ASTJSON/long_type_name_binary_operation_legacy.json index 977f783dd..6ad38d194 100644 --- a/test/libsolidity/ASTJSON/long_type_name_binary_operation_legacy.json +++ b/test/libsolidity/ASTJSON/long_type_name_binary_operation_legacy.json @@ -100,6 +100,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "a", "overrides": null, "scope": 9, diff --git a/test/libsolidity/ASTJSON/long_type_name_identifier.json b/test/libsolidity/ASTJSON/long_type_name_identifier.json index 5c8951d29..eddeacd04 100644 --- a/test/libsolidity/ASTJSON/long_type_name_identifier.json +++ b/test/libsolidity/ASTJSON/long_type_name_identifier.json @@ -30,6 +30,7 @@ { "constant": false, "id": 3, + "mutability": "mutable", "name": "a", "nodeType": "VariableDeclaration", "overrides": null, @@ -87,6 +88,7 @@ { "constant": false, "id": 10, + "mutability": "mutable", "name": "b", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json b/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json index caf807c24..bc90e0d6a 100644 --- a/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json +++ b/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json @@ -40,6 +40,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "a", "overrides": null, "scope": 15, @@ -143,6 +144,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "b", "overrides": null, "scope": 13, diff --git a/test/libsolidity/ASTJSON/mappings.json b/test/libsolidity/ASTJSON/mappings.json index 0bd1ecd98..5c24e3a12 100644 --- a/test/libsolidity/ASTJSON/mappings.json +++ b/test/libsolidity/ASTJSON/mappings.json @@ -58,6 +58,7 @@ { "constant": false, "id": 8, + "mutability": "mutable", "name": "a", "nodeType": "VariableDeclaration", "overrides": null, @@ -113,6 +114,7 @@ { "constant": false, "id": 12, + "mutability": "mutable", "name": "b", "nodeType": "VariableDeclaration", "overrides": null, @@ -166,6 +168,7 @@ { "constant": false, "id": 16, + "mutability": "mutable", "name": "c", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/mappings_legacy.json b/test/libsolidity/ASTJSON/mappings_legacy.json index 79814effe..700097b66 100644 --- a/test/libsolidity/ASTJSON/mappings_legacy.json +++ b/test/libsolidity/ASTJSON/mappings_legacy.json @@ -80,6 +80,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "a", "overrides": null, "scope": 17, @@ -134,6 +135,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "b", "overrides": null, "scope": 17, @@ -186,6 +188,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "c", "overrides": null, "scope": 17, diff --git a/test/libsolidity/ASTJSON/modifier_definition.json b/test/libsolidity/ASTJSON/modifier_definition.json index 19f7ed184..a3c71159a 100644 --- a/test/libsolidity/ASTJSON/modifier_definition.json +++ b/test/libsolidity/ASTJSON/modifier_definition.json @@ -56,6 +56,7 @@ { "constant": false, "id": 2, + "mutability": "mutable", "name": "i", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/modifier_definition_legacy.json b/test/libsolidity/ASTJSON/modifier_definition_legacy.json index 8f028a474..369562171 100644 --- a/test/libsolidity/ASTJSON/modifier_definition_legacy.json +++ b/test/libsolidity/ASTJSON/modifier_definition_legacy.json @@ -54,6 +54,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "i", "overrides": null, "scope": 6, diff --git a/test/libsolidity/ASTJSON/modifier_invocation.json b/test/libsolidity/ASTJSON/modifier_invocation.json index 19f7ed184..a3c71159a 100644 --- a/test/libsolidity/ASTJSON/modifier_invocation.json +++ b/test/libsolidity/ASTJSON/modifier_invocation.json @@ -56,6 +56,7 @@ { "constant": false, "id": 2, + "mutability": "mutable", "name": "i", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/modifier_invocation_legacy.json b/test/libsolidity/ASTJSON/modifier_invocation_legacy.json index 8f028a474..369562171 100644 --- a/test/libsolidity/ASTJSON/modifier_invocation_legacy.json +++ b/test/libsolidity/ASTJSON/modifier_invocation_legacy.json @@ -54,6 +54,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "i", "overrides": null, "scope": 6, diff --git a/test/libsolidity/ASTJSON/mutability.json b/test/libsolidity/ASTJSON/mutability.json new file mode 100644 index 000000000..81d668702 --- /dev/null +++ b/test/libsolidity/ASTJSON/mutability.json @@ -0,0 +1,189 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 10 + ] + }, + "id": 11, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 10, + "linearizedBaseContracts": + [ + 10 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "constant": false, + "functionSelector": "0dbe671f", + "id": 3, + "mutability": "immutable", + "name": "a", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 10, + "src": "17:27:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "17:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": + { + "argumentTypes": null, + "hexValue": "34", + "id": 2, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "43:1:1", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "visibility": "public" + }, + { + "constant": true, + "functionSelector": "4df7e3d0", + "id": 6, + "mutability": "constant", + "name": "b", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 10, + "src": "50:26:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 4, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "50:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": + { + "argumentTypes": null, + "hexValue": "32", + "id": 5, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "75:1:1", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "visibility": "public" + }, + { + "constant": false, + "functionSelector": "c3da42b8", + "id": 9, + "mutability": "mutable", + "name": "c", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 10, + "src": "82:17:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 7, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "82:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": + { + "argumentTypes": null, + "hexValue": "33", + "id": 8, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "98:1:1", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + }, + "visibility": "public" + } + ], + "scope": 11, + "src": "0:102:1" + } + ], + "src": "0:103:1" +} diff --git a/test/libsolidity/ASTJSON/mutability.sol b/test/libsolidity/ASTJSON/mutability.sol new file mode 100644 index 000000000..7688186e7 --- /dev/null +++ b/test/libsolidity/ASTJSON/mutability.sol @@ -0,0 +1,8 @@ +contract C +{ + uint public immutable a = 4; + uint public constant b = 2; + uint public c = 3; +} + +// ---- diff --git a/test/libsolidity/ASTJSON/mutability_legacy.json b/test/libsolidity/ASTJSON/mutability_legacy.json new file mode 100644 index 000000000..98f28f636 --- /dev/null +++ b/test/libsolidity/ASTJSON/mutability_legacy.json @@ -0,0 +1,195 @@ +{ + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 10 + ] + } + }, + "children": + [ + { + "attributes": + { + "abstract": false, + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 10 + ], + "name": "C", + "scope": 11 + }, + "children": + [ + { + "attributes": + { + "constant": false, + "functionSelector": "0dbe671f", + "mutability": "immutable", + "name": "a", + "overrides": null, + "scope": 10, + "stateVariable": true, + "storageLocation": "default", + "type": "uint256", + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 1, + "name": "ElementaryTypeName", + "src": "17:4:1" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "34", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 4", + "value": "4" + }, + "id": 2, + "name": "Literal", + "src": "43:1:1" + } + ], + "id": 3, + "name": "VariableDeclaration", + "src": "17:27:1" + }, + { + "attributes": + { + "constant": true, + "functionSelector": "4df7e3d0", + "mutability": "constant", + "name": "b", + "overrides": null, + "scope": 10, + "stateVariable": true, + "storageLocation": "default", + "type": "uint256", + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 4, + "name": "ElementaryTypeName", + "src": "50:4:1" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "32", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 2", + "value": "2" + }, + "id": 5, + "name": "Literal", + "src": "75:1:1" + } + ], + "id": 6, + "name": "VariableDeclaration", + "src": "50:26:1" + }, + { + "attributes": + { + "constant": false, + "functionSelector": "c3da42b8", + "mutability": "mutable", + "name": "c", + "overrides": null, + "scope": 10, + "stateVariable": true, + "storageLocation": "default", + "type": "uint256", + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 7, + "name": "ElementaryTypeName", + "src": "82:4:1" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "33", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 3", + "value": "3" + }, + "id": 8, + "name": "Literal", + "src": "98:1:1" + } + ], + "id": 9, + "name": "VariableDeclaration", + "src": "82:17:1" + } + ], + "id": 10, + "name": "ContractDefinition", + "src": "0:102:1" + } + ], + "id": 11, + "name": "SourceUnit", + "src": "0:103:1" +} diff --git a/test/libsolidity/ASTJSON/non_utf8.json b/test/libsolidity/ASTJSON/non_utf8.json index 18f6b12dc..c925389d7 100644 --- a/test/libsolidity/ASTJSON/non_utf8.json +++ b/test/libsolidity/ASTJSON/non_utf8.json @@ -45,6 +45,7 @@ { "constant": false, "id": 3, + "mutability": "mutable", "name": "x", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/non_utf8_legacy.json b/test/libsolidity/ASTJSON/non_utf8_legacy.json index 9f7933020..d3a212b0c 100644 --- a/test/libsolidity/ASTJSON/non_utf8_legacy.json +++ b/test/libsolidity/ASTJSON/non_utf8_legacy.json @@ -100,6 +100,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "x", "overrides": null, "scope": 6, diff --git a/test/libsolidity/ASTJSON/short_type_name.json b/test/libsolidity/ASTJSON/short_type_name.json index 887f29a1d..75defa9ab 100644 --- a/test/libsolidity/ASTJSON/short_type_name.json +++ b/test/libsolidity/ASTJSON/short_type_name.json @@ -45,6 +45,7 @@ { "constant": false, "id": 7, + "mutability": "mutable", "name": "x", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/short_type_name_legacy.json b/test/libsolidity/ASTJSON/short_type_name_legacy.json index 4d1de106b..0d428bcb1 100644 --- a/test/libsolidity/ASTJSON/short_type_name_legacy.json +++ b/test/libsolidity/ASTJSON/short_type_name_legacy.json @@ -101,6 +101,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "x", "overrides": null, "scope": 9, diff --git a/test/libsolidity/ASTJSON/short_type_name_ref.json b/test/libsolidity/ASTJSON/short_type_name_ref.json index 501184c9c..46096a914 100644 --- a/test/libsolidity/ASTJSON/short_type_name_ref.json +++ b/test/libsolidity/ASTJSON/short_type_name_ref.json @@ -45,6 +45,7 @@ { "constant": false, "id": 8, + "mutability": "mutable", "name": "rows", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json b/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json index 4eec368b6..b1f4b88d2 100644 --- a/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json +++ b/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json @@ -101,6 +101,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "rows", "overrides": null, "scope": 10, diff --git a/test/libsolidity/ASTJSON/source_location.json b/test/libsolidity/ASTJSON/source_location.json index cc6dd33c9..54bffe378 100644 --- a/test/libsolidity/ASTJSON/source_location.json +++ b/test/libsolidity/ASTJSON/source_location.json @@ -45,6 +45,7 @@ { "constant": false, "id": 3, + "mutability": "mutable", "name": "x", "nodeType": "VariableDeclaration", "overrides": null, diff --git a/test/libsolidity/ASTJSON/source_location_legacy.json b/test/libsolidity/ASTJSON/source_location_legacy.json index dfde18975..dbd578dd2 100644 --- a/test/libsolidity/ASTJSON/source_location_legacy.json +++ b/test/libsolidity/ASTJSON/source_location_legacy.json @@ -100,6 +100,7 @@ "attributes": { "constant": false, + "mutability": "mutable", "name": "x", "overrides": null, "scope": 9, diff --git a/test/libsolidity/SMTChecker.cpp b/test/libsolidity/SMTChecker.cpp index 06862ad08..6df19c1c7 100644 --- a/test/libsolidity/SMTChecker.cpp +++ b/test/libsolidity/SMTChecker.cpp @@ -34,14 +34,14 @@ namespace solidity::frontend::test class SMTCheckerFramework: public AnalysisFramework { protected: - virtual std::pair + std::pair parseAnalyseAndReturnError( std::string const& _source, bool _reportWarnings = false, bool _insertVersionPragma = true, bool _allowMultipleErrors = false, bool _allowRecoveryErrors = false - ) + ) override { return AnalysisFramework::parseAnalyseAndReturnError( "pragma experimental SMTChecker;\n" + _source, diff --git a/test/libsolidity/SolidityExecutionFramework.h b/test/libsolidity/SolidityExecutionFramework.h index aaa17525f..2410195fa 100644 --- a/test/libsolidity/SolidityExecutionFramework.h +++ b/test/libsolidity/SolidityExecutionFramework.h @@ -46,7 +46,7 @@ public: ExecutionFramework(_evmVersion), m_showMetadata(solidity::test::CommonOptions::get().showMetadata) {} - virtual bytes const& compileAndRunWithoutCheck( + bytes const& compileAndRunWithoutCheck( std::string const& _sourceCode, u256 const& _value = 0, std::string const& _contractName = "", diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp index cdaee104b..5dfefc0b7 100644 --- a/test/libsolidity/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -52,15 +52,15 @@ public: FirstExpressionExtractor(ASTNode& _node): m_expression(nullptr) { _node.accept(*this); } Expression* expression() const { return m_expression; } private: - virtual bool visit(Assignment& _expression) override { return checkExpression(_expression); } - virtual bool visit(UnaryOperation& _expression) override { return checkExpression(_expression); } - virtual bool visit(BinaryOperation& _expression) override { return checkExpression(_expression); } - virtual bool visit(FunctionCall& _expression) override { return checkExpression(_expression); } - virtual bool visit(MemberAccess& _expression) override { return checkExpression(_expression); } - virtual bool visit(IndexAccess& _expression) override { return checkExpression(_expression); } - virtual bool visit(Identifier& _expression) override { return checkExpression(_expression); } - virtual bool visit(ElementaryTypeNameExpression& _expression) override { return checkExpression(_expression); } - virtual bool visit(Literal& _expression) override { return checkExpression(_expression); } + bool visit(Assignment& _expression) override { return checkExpression(_expression); } + bool visit(UnaryOperation& _expression) override { return checkExpression(_expression); } + bool visit(BinaryOperation& _expression) override { return checkExpression(_expression); } + bool visit(FunctionCall& _expression) override { return checkExpression(_expression); } + bool visit(MemberAccess& _expression) override { return checkExpression(_expression); } + bool visit(IndexAccess& _expression) override { return checkExpression(_expression); } + bool visit(Identifier& _expression) override { return checkExpression(_expression); } + bool visit(ElementaryTypeNameExpression& _expression) override { return checkExpression(_expression); } + bool visit(Literal& _expression) override { return checkExpression(_expression); } bool checkExpression(Expression& _expression) { if (m_expression == nullptr) diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index 192a26898..12fbc3fce 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -672,7 +672,7 @@ BOOST_AUTO_TEST_CASE(inline_asm_end_location) { public: bool visited = false; - virtual bool visit(InlineAssembly const& _inlineAsm) + bool visit(InlineAssembly const& _inlineAsm) override { auto loc = _inlineAsm.location(); auto asmStr = loc.source->source().substr(loc.start, loc.end - loc.start); diff --git a/test/libsolidity/semanticTests/types/tuple_in_tuple.sol b/test/libsolidity/semanticTests/types/nested_tuples.sol similarity index 100% rename from test/libsolidity/semanticTests/types/tuple_in_tuple.sol rename to test/libsolidity/semanticTests/types/nested_tuples.sol diff --git a/test/libsolidity/semanticTests/types/nested_tuples_noyul.sol b/test/libsolidity/semanticTests/types/nested_tuples_noyul.sol new file mode 100644 index 000000000..1eff9e2b9 --- /dev/null +++ b/test/libsolidity/semanticTests/types/nested_tuples_noyul.sol @@ -0,0 +1,17 @@ +contract test { + function f3() public returns(int) { + int a = 3; + ((, ), ) = ((7, 8), 9); + return a; + } + function f4() public returns(int) { + int a; + (a, ) = (4, (8, 16, 32)); + return a; + } +} +// ==== +// compileViaYul: false +// ---- +// f3() -> 3 +// f4() -> 4 diff --git a/test/libsolidity/semanticTests/types/tuple_assign_multi_slot_grow.sol b/test/libsolidity/semanticTests/types/tuple_assign_multi_slot_grow.sol new file mode 100644 index 000000000..6735563b9 --- /dev/null +++ b/test/libsolidity/semanticTests/types/tuple_assign_multi_slot_grow.sol @@ -0,0 +1,13 @@ +contract C { + + function f() public pure returns (uint, uint, uint) { + bytes memory a; bytes memory b; bytes memory c; + (a, (b, c)) = ("0", ("1", "2")); + return (uint8(a[0]), uint8(b[0]), uint8(c[0])); + } + +} +// ==== +// compileViaYul: also +// ---- +// f() -> 0x30, 0x31, 0x32 diff --git a/test/libsolidity/smtCheckerTests/functions/internal_call_inheritance.sol b/test/libsolidity/smtCheckerTests/functions/internal_call_inheritance.sol new file mode 100644 index 000000000..5332dc590 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/functions/internal_call_inheritance.sol @@ -0,0 +1,20 @@ +pragma experimental SMTChecker; + +contract C { + function c() public pure returns (uint) { return 42; } +} + +contract B is C { + function b() public pure returns (uint) { return c(); } +} + +contract A is B { + uint public x; + + function a() public { + x = b(); + assert(x < 40); + } +} +// ---- +// Warning: (254-268): Assertion violation happens here diff --git a/test/libsolidity/smtCheckerTests/functions/internal_call_inheritance_2.sol b/test/libsolidity/smtCheckerTests/functions/internal_call_inheritance_2.sol new file mode 100644 index 000000000..262f0e498 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/functions/internal_call_inheritance_2.sol @@ -0,0 +1,24 @@ +pragma experimental SMTChecker; + +contract C { + uint y; + function c(uint _y) public returns (uint) { + y = _y; + return y; + } +} + +contract B is C { + function b() public returns (uint) { return c(42); } +} + +contract A is B { + uint public x; + + function a() public { + x = b(); + assert(x < 40); + } +} +// ---- +// Warning: (274-288): Assertion violation happens here diff --git a/test/libsolidity/syntaxTests/immutable/double_specifier.sol b/test/libsolidity/syntaxTests/immutable/double_specifier.sol index 39f0f1e76..fec0f823b 100644 --- a/test/libsolidity/syntaxTests/immutable/double_specifier.sol +++ b/test/libsolidity/syntaxTests/immutable/double_specifier.sol @@ -3,5 +3,5 @@ contract C { uint immutable constant x; } // ---- -// ParserError: (32-41): Constantness already set to "immutable" -// ParserError: (64-72): Constantness already set to "immutable" +// ParserError: (32-41): Mutability already set to "immutable" +// ParserError: (64-72): Mutability already set to "immutable" diff --git a/test/libsolidity/syntaxTests/specialFunctions/functionCallOptions_err.sol b/test/libsolidity/syntaxTests/specialFunctions/functionCallOptions_err.sol new file mode 100644 index 000000000..5ad8c4e5f --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/functionCallOptions_err.sol @@ -0,0 +1,11 @@ +contract C { + function f() public payable { + abi.encode(this.f{value: 2}); + abi.encode(this.f{gas: 2}); + abi.encode(this.f{value: 2, gas: 1}); + } +} +// ---- +// TypeError: (60-76): This type cannot be encoded. +// TypeError: (92-106): This type cannot be encoded. +// TypeError: (122-146): This type cannot be encoded. diff --git a/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_internal_functions.sol b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_internal_functions.sol index ea11703f9..eac453939 100644 --- a/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_internal_functions.sol +++ b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_internal_functions.sol @@ -1,12 +1,11 @@ contract C { function f() public pure { - bytes32 h = keccak256(abi.encodePacked(keccak256, f, this.f.gas, blockhash)); + bytes32 h = keccak256(abi.encodePacked(keccak256, f, this.f{gas: 2}, blockhash)); h; } } // ---- -// Warning: (105-115): Using ".gas(...)" is deprecated. Use "{gas: ...}" instead. // TypeError: (91-100): This type cannot be encoded. // TypeError: (102-103): This type cannot be encoded. -// TypeError: (105-115): This type cannot be encoded. -// TypeError: (117-126): This type cannot be encoded. +// TypeError: (105-119): This type cannot be encoded. +// TypeError: (121-130): This type cannot be encoded. diff --git a/test/libsolutil/StringUtils.cpp b/test/libsolutil/StringUtils.cpp index b7e653a0e..e50260e88 100644 --- a/test/libsolutil/StringUtils.cpp +++ b/test/libsolutil/StringUtils.cpp @@ -76,13 +76,13 @@ BOOST_AUTO_TEST_CASE(test_alternatives_list) { vector strings; BOOST_CHECK_EQUAL(quotedAlternativesList(strings), ""); - strings.push_back("a"); + strings.emplace_back("a"); BOOST_CHECK_EQUAL(quotedAlternativesList(strings), "\"a\""); - strings.push_back("b"); + strings.emplace_back("b"); BOOST_CHECK_EQUAL(quotedAlternativesList(strings), "\"a\" or \"b\""); - strings.push_back("c"); + strings.emplace_back("c"); BOOST_CHECK_EQUAL(quotedAlternativesList(strings), "\"a\", \"b\" or \"c\""); - strings.push_back("d"); + strings.emplace_back("d"); BOOST_CHECK_EQUAL(quotedAlternativesList(strings), "\"a\", \"b\", \"c\" or \"d\""); } diff --git a/test/libyul/FunctionSideEffects.cpp b/test/libyul/FunctionSideEffects.cpp index db3a39df0..3d3461b0e 100644 --- a/test/libyul/FunctionSideEffects.cpp +++ b/test/libyul/FunctionSideEffects.cpp @@ -47,15 +47,15 @@ string toString(SideEffects const& _sideEffects) { vector ret; if (_sideEffects.movable) - ret.push_back("movable"); + ret.emplace_back("movable"); if (_sideEffects.sideEffectFree) - ret.push_back("sideEffectFree"); + ret.emplace_back("sideEffectFree"); if (_sideEffects.sideEffectFreeIfNoMSize) - ret.push_back("sideEffectFreeIfNoMSize"); + ret.emplace_back("sideEffectFreeIfNoMSize"); if (_sideEffects.invalidatesStorage) - ret.push_back("invalidatesStorage"); + ret.emplace_back("invalidatesStorage"); if (_sideEffects.invalidatesMemory) - ret.push_back("invalidatesMemory"); + ret.emplace_back("invalidatesMemory"); return joinHumanReadable(ret); } } diff --git a/test/libyul/SyntaxTest.h b/test/libyul/SyntaxTest.h index b4c838b54..342aa2845 100644 --- a/test/libyul/SyntaxTest.h +++ b/test/libyul/SyntaxTest.h @@ -37,7 +37,7 @@ public: return std::make_unique(_config.filename, _config.evmVersion); } SyntaxTest(std::string const& _filename, langutil::EVMVersion _evmVersion); - virtual ~SyntaxTest() {} + ~SyntaxTest() override {} protected: void parseAndAnalyze() override; diff --git a/test/tools/afl_fuzzer.cpp b/test/tools/afl_fuzzer.cpp index eff4bc55a..81c3a2bfc 100644 --- a/test/tools/afl_fuzzer.cpp +++ b/test/tools/afl_fuzzer.cpp @@ -104,7 +104,7 @@ Allowed options)", else if (arguments.count("input-files")) inputs = arguments["input-files"].as>(); else - inputs.push_back(""); + inputs.emplace_back(""); bool optimize = !arguments.count("without-optimizer"); int retResult = 0; diff --git a/test/tools/yulInterpreter/Interpreter.cpp b/test/tools/yulInterpreter/Interpreter.cpp index cbfdbbe52..6f989b873 100644 --- a/test/tools/yulInterpreter/Interpreter.cpp +++ b/test/tools/yulInterpreter/Interpreter.cpp @@ -308,7 +308,7 @@ pair< for (auto const& scope: m_scopes) { // Copy over all functions. - newScopes.push_back({}); + newScopes.emplace_back(); for (auto const& [name, funDef]: scope) if (funDef) newScopes.back().emplace(name, funDef); diff --git a/test/tools/yulInterpreter/Interpreter.h b/test/tools/yulInterpreter/Interpreter.h index ab0386165..f50cbe6c4 100644 --- a/test/tools/yulInterpreter/Interpreter.h +++ b/test/tools/yulInterpreter/Interpreter.h @@ -136,7 +136,7 @@ private: /// Evaluates the expression and returns its value. std::vector evaluateMulti(Expression const& _expression); - void openScope() { m_scopes.push_back({}); } + void openScope() { m_scopes.emplace_back(); } /// Unregisters variables and functions. void closeScope(); diff --git a/tools/solidityUpgrade/Upgrade050.cpp b/tools/solidityUpgrade/Upgrade050.cpp index ac939c2a1..18a495080 100644 --- a/tools/solidityUpgrade/Upgrade050.cpp +++ b/tools/solidityUpgrade/Upgrade050.cpp @@ -32,8 +32,7 @@ void ConstructorKeyword::endVisit(ContractDefinition const& _contract) { for (auto const* function: _contract.definedFunctions()) if (function->name() == _contract.name()) - m_changes.push_back( - UpgradeChange{ + m_changes.emplace_back( UpgradeChange::Level::Safe, function->location(), SourceTransform::replaceFunctionName( @@ -41,18 +40,15 @@ void ConstructorKeyword::endVisit(ContractDefinition const& _contract) function->name(), "constructor" ) - } ); } void VisibilitySpecifier::endVisit(FunctionDefinition const& _function) { if (_function.noVisibilitySpecified()) - m_changes.push_back( - UpgradeChange{ + m_changes.emplace_back( UpgradeChange::Level::Safe, _function.location(), SourceTransform::insertAfterRightParenthesis(_function.location(), "public") - } ); } diff --git a/tools/solidityUpgrade/Upgrade050.h b/tools/solidityUpgrade/Upgrade050.h index d85b69912..58670e7b2 100644 --- a/tools/solidityUpgrade/Upgrade050.h +++ b/tools/solidityUpgrade/Upgrade050.h @@ -37,7 +37,7 @@ public: void analyze(frontend::SourceUnit const& _sourceUnit) { _sourceUnit.accept(*this); } private: - void endVisit(frontend::ContractDefinition const& _contract); + void endVisit(frontend::ContractDefinition const& _contract) override; }; /** @@ -52,7 +52,7 @@ public: void analyze(frontend::SourceUnit const& _sourceUnit) { _sourceUnit.accept(*this); } private: - void endVisit(frontend::FunctionDefinition const& _function); + void endVisit(frontend::FunctionDefinition const& _function) override; }; } diff --git a/tools/solidityUpgrade/Upgrade060.cpp b/tools/solidityUpgrade/Upgrade060.cpp index 9cd996f53..9ed7cbc74 100644 --- a/tools/solidityUpgrade/Upgrade060.cpp +++ b/tools/solidityUpgrade/Upgrade060.cpp @@ -106,12 +106,10 @@ void AbstractContract::endVisit(ContractDefinition const& _contract) !_contract.abstract() && !_contract.isInterface() ) - m_changes.push_back( - UpgradeChange{ + m_changes.emplace_back( UpgradeChange::Level::Safe, _contract.location(), SourceTransform::insertBeforeKeyword(_contract.location(), "contract", "abstract") - } ); } @@ -132,12 +130,10 @@ void OverridingFunction::endVisit(ContractDefinition const& _contract) /// Add override with contract list, if needed. if (!function->overrides() && expectedContracts.size() > 1) - m_changes.push_back( - UpgradeChange{ + m_changes.emplace_back( UpgradeChange::Level::Safe, function->location(), appendOverride(*function, expectedContracts) - } ); for (auto [begin, end] = inheritedFunctions.equal_range(proxy); begin != end; begin++) @@ -151,12 +147,10 @@ void OverridingFunction::endVisit(ContractDefinition const& _contract) /// If function does not specify override and no override with /// contract list was added before. if (!function->overrides() && expectedContracts.size() <= 1) - m_changes.push_back( - UpgradeChange{ + m_changes.emplace_back( UpgradeChange::Level::Safe, function->location(), appendOverride(*function, expectedContracts) - } ); } } @@ -181,12 +175,10 @@ void VirtualFunction::endVisit(ContractDefinition const& _contract) function->visibility() > Visibility::Private ) { - m_changes.push_back( - UpgradeChange{ + m_changes.emplace_back( UpgradeChange::Level::Safe, function->location(), appendVirtual(*function) - } ); } @@ -198,12 +190,10 @@ void VirtualFunction::endVisit(ContractDefinition const& _contract) !super.virtualSemantics() ) { - m_changes.push_back( - UpgradeChange{ + m_changes.emplace_back( UpgradeChange::Level::Safe, function->location(), appendVirtual(*function) - } ); } } diff --git a/tools/solidityUpgrade/Upgrade060.h b/tools/solidityUpgrade/Upgrade060.h index ea29d3a7b..e2386d104 100644 --- a/tools/solidityUpgrade/Upgrade060.h +++ b/tools/solidityUpgrade/Upgrade060.h @@ -35,7 +35,7 @@ public: void analyze(frontend::SourceUnit const& _sourceUnit) { _sourceUnit.accept(*this); } private: - void endVisit(frontend::ContractDefinition const& _contract); + void endVisit(frontend::ContractDefinition const& _contract) override; }; /** @@ -49,7 +49,7 @@ public: void analyze(frontend::SourceUnit const& _sourceUnit) { _sourceUnit.accept(*this); } private: - void endVisit(frontend::ContractDefinition const& _contract); + void endVisit(frontend::ContractDefinition const& _contract) override; }; /** @@ -63,7 +63,7 @@ public: void analyze(frontend::SourceUnit const& _sourceUnit) { _sourceUnit.accept(*this); } private: - void endVisit(frontend::ContractDefinition const& _function); + void endVisit(frontend::ContractDefinition const& _function) override; }; } diff --git a/tools/yulPhaser/PairSelections.cpp b/tools/yulPhaser/PairSelections.cpp index 8f3fd0f7f..7b707dec8 100644 --- a/tools/yulPhaser/PairSelections.cpp +++ b/tools/yulPhaser/PairSelections.cpp @@ -41,7 +41,7 @@ vector> RandomPairSelection::materialise(size_t _poolSize) index2 = SimulationRNG::uniformInt(0, _poolSize - 1); } while (index1 == index2); - selection.push_back({index1, index2}); + selection.emplace_back(index1, index2); } return selection; @@ -58,7 +58,7 @@ vector> PairMosaicSelection::materialise(size_t _poolSize) for (size_t i = 0; i < count; ++i) { tuple pair = m_pattern[i % m_pattern.size()]; - selection.push_back({min(get<0>(pair), _poolSize - 1), min(get<1>(pair), _poolSize - 1)}); + selection.emplace_back(min(get<0>(pair), _poolSize - 1), min(get<1>(pair), _poolSize - 1)); } return selection;