diff --git a/.circleci/config.yml b/.circleci/config.yml index a4a7605d2..784b561d9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -862,7 +862,7 @@ jobs: - gitter_notify_failure_unless_pr t_ubu_codecov: - <<: *base_ubuntu2004 + <<: *base_ubuntu2004_large environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 1 @@ -1099,7 +1099,7 @@ jobs: t_ubu_asan_cli: # Runs slightly faster on medium but we only run it nightly so efficiency matters more. - <<: *base_ubuntu2004_small + <<: *base_ubuntu2004 environment: TERM: xterm ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2 diff --git a/.gitignore b/.gitignore index 4f1717181..773f09be6 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ emscripten_build/ /docs/_build /docs/_static/robots.txt /deps +/reports # vim stuff [._]*.sw[a-p] diff --git a/CMakeLists.txt b/CMakeLists.txt index b43f24494..d04d708ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,7 @@ configure_file("${CMAKE_SOURCE_DIR}/cmake/templates/license.h.in" include/licens include(EthOptions) configure_project(TESTS) set(LATEST_Z3_VERSION "4.11.2") -set(MINIMUM_Z3_VERSION "4.8.0") +set(MINIMUM_Z3_VERSION "4.8.16") find_package(Z3) if (${Z3_FOUND}) if (${STRICT_Z3_VERSION}) diff --git a/Changelog.md b/Changelog.md index 17294f6b2..52addbb6b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,7 @@ Compiler Features: * Standard JSON: Add a boolean field `settings.metadata.appendCBOR` that skips CBOR metadata from getting appended at the end of the bytecode. * Yul EVM Code Transform: Generate more optimal code for user-defined functions that always terminate a transaction. No return labels will be pushed for calls to functions that always terminate. * Yul Optimizer: Allow replacing the previously hard-coded cleanup sequence by specifying custom steps after a colon delimiter (``:``) in the sequence string. + * Yul Optimizer: Eliminate ``keccak256`` calls if the value was already calculated by a previous call and can be reused. * Language Server: Add basic document hover support. * Optimizer: Added optimization rule ``and(shl(X, Y), shl(X, Z)) => shl(X, and(Y, Z))``. * SMTChecker: Support Eldarica as a Horn solver for the CHC engine when using the CLI option ``--model-checker-solvers eld``. The binary `eld` must be available in the system. diff --git a/ReviewChecklist.md b/ReviewChecklist.md index c44c56215..c85a50546 100644 --- a/ReviewChecklist.md +++ b/ReviewChecklist.md @@ -143,7 +143,7 @@ The following points are all covered by the coding style but come up so often th Values of types that cannot be named: literals, tuples, array slices, storage references? - [ ] If it accepts a function, does it also accept an event or an error? These have function types but are not functions. - [ ] If it affects free functions, what about internal library functions? - - [ ] Bound library functions? Functions bound with `using for`? + - [ ] Attached library functions? Functions attached with `using for`? - [ ] Possible combinations of `storage`, `memory`, `calldata`, `immutable`, `constant`? Remember that internal functions can take `storage` arguments. - [ ] Does it work at construction time as well? What if you store it at construction time and read after deployment? diff --git a/docs/_static/img/favicon.png b/docs/_static/img/favicon.png new file mode 100644 index 000000000..3991d87e9 Binary files /dev/null and b/docs/_static/img/favicon.png differ diff --git a/docs/cheatsheet.rst b/docs/cheatsheet.rst index 3a7d478b1..412678953 100644 --- a/docs/cheatsheet.rst +++ b/docs/cheatsheet.rst @@ -24,7 +24,7 @@ Global Variables - ``abi.encodeCall(function functionPointer, (...)) returns (bytes memory)``: ABI-encodes a call to ``functionPointer`` with the arguments found in the tuple. Performs a full type-check, ensuring the types match the function signature. Result equals ``abi.encodeWithSelector(functionPointer.selector, (...))`` - ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent - to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)`` + to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`` - ``bytes.concat(...) returns (bytes memory)``: :ref:`Concatenates variable number of arguments to one byte array` - ``string.concat(...) returns (string memory)``: :ref:`Concatenates variable number of diff --git a/docs/conf.py b/docs/conf.py index 10aa406f2..61df2b53e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -152,7 +152,7 @@ html_logo = "logo.svg" # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +html_favicon = "_static/img/favicon.png" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/docs/contracts/using-for.rst b/docs/contracts/using-for.rst index b4a60585a..20299e1a4 100644 --- a/docs/contracts/using-for.rst +++ b/docs/contracts/using-for.rst @@ -16,23 +16,24 @@ at contract level. The first part, ``A``, can be one of: -- a list of file-level or library functions (``using {f, g, h, L.t} for uint;``) - - only those functions will be attached to the type. -- the name of a library (``using L for uint;``) - - all functions (both public and internal ones) of the library are attached to the type +- A list of file-level or library functions (e.g. ``using {f, g, h, L.t} for uint;``) - + only those functions will be attached to the type as member functions. + Note that private library functions can only be specified when ``using for`` is inside the library. +- The name of a library (e.g. ``using L for uint;``) - + all non-private functions of the library are attached to the type. At file level, the second part, ``B``, has to be an explicit type (without data location specifier). -Inside contracts, you can also use ``using L for *;``, +Inside contracts, you can also use ``*`` in place of the type (e.g. ``using L for *;``), which has the effect that all functions of the library ``L`` are attached to *all* types. -If you specify a library, *all* functions in the library are attached, +If you specify a library, *all* functions in the library get attached, even those where the type of the first parameter does not match the type of the object. The type is checked at the point the function is called and function overload resolution is performed. -If you use a list of functions (``using {f, g, h, L.t} for uint;``), +If you use a list of functions (e.g. ``using {f, g, h, L.t} for uint;``), then the type (``uint``) has to be implicitly convertible to the first parameter of each of these functions. This check is performed even if none of these functions are called. diff --git a/docs/grammar/SolidityParser.g4 b/docs/grammar/SolidityParser.g4 index 92718b975..306874989 100644 --- a/docs/grammar/SolidityParser.g4 +++ b/docs/grammar/SolidityParser.g4 @@ -312,7 +312,7 @@ errorDefinition: Semicolon; /** - * Using directive to bind library functions and free functions to types. + * Using directive to attach library functions and free functions to types. * Can occur within contracts and libraries and at the file level. */ usingDirective: Using (identifierPath | (LBrace identifierPath (Comma identifierPath)* RBrace)) For (Mul | typeName) Global? Semicolon; diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 9a613d75d..1b6ac6635 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -326,7 +326,7 @@ The following are dependencies for all builds of Solidity: +-----------------------------------+-------------------------------------------------------+ | `Git`_ | Command-line tool for retrieving source code. | +-----------------------------------+-------------------------------------------------------+ -| `z3`_ (version 4.8+, Optional) | For use with SMT checker. | +| `z3`_ (version 4.8.16+, Optional) | For use with SMT checker. | +-----------------------------------+-------------------------------------------------------+ | `cvc4`_ (Optional) | For use with SMT checker. | +-----------------------------------+-------------------------------------------------------+ diff --git a/docs/resources.rst b/docs/resources.rst index 3b403cd6d..9084037d9 100644 --- a/docs/resources.rst +++ b/docs/resources.rst @@ -43,17 +43,6 @@ Integrated (Ethereum) Development Environments Editor Integrations =================== -* Atom - - * `Etheratom `_ - Plugin for the Atom editor that features syntax highlighting, compilation and a runtime environment (Backend node & VM compatible). - - * `Atom Solidity Linter `_ - Plugin for the Atom editor that provides Solidity linting. - - * `Atom Solium Linter `_ - Configurable Solidity linter for Atom using Solium (now Ethlint) as a base. - * Emacs * `Emacs Solidity `_ @@ -62,31 +51,40 @@ Editor Integrations * IntelliJ * `IntelliJ IDEA plugin `_ - Solidity plugin for IntelliJ IDEA (and all other JetBrains IDEs) + Solidity plugin for IntelliJ IDEA (and all other JetBrains IDEs). -* Sublime +* Sublime Text * `Package for SublimeText - Solidity language syntax `_ Solidity syntax highlighting for SublimeText editor. * Vim - * `Vim Solidity `_ - Plugin for the Vim editor providing syntax highlighting. + * `Vim Solidity by Thesis `_ + Syntax highlighting for Solidity in Vim. + + * `Vim Solidity by TovarishFin `_ + Vim syntax file for Solidity. * `Vim Syntastic `_ Plugin for the Vim editor providing compile checking. -* Visual Studio Code +* Visual Studio Code (VS Code) - * `Visual Studio Code extension `_ + * `Ethereum Remix Visual Studio Code extension `_ + Ethereum Remix extension pack for VS Code + + * `Solidity Visual Studio Code extension, by Juan Blanco `_ Solidity plugin for Microsoft Visual Studio Code that includes syntax highlighting and the Solidity compiler. + * `Solidity Visual Studio Code extension, by Nomic Foundation `_ + Solidity and Hardhat support by the Hardhat team, including: syntax highlighting, jump to definition, renames, quick fixes and inline solc warnings and errors. + * `Solidity Visual Auditor extension `_ Adds security centric syntax and semantic highlighting to Visual Studio Code. - * `Hardhat + Solidity Visual Studio Code extension `_ - Solidity and Hardhat support by the Hardhat team. + * `Truffle for VS Code `_ + Build, debug and deploy smart contracts on Ethereum and EVM-compatible blockchains. Solidity Tools ============== diff --git a/docs/smtchecker.rst b/docs/smtchecker.rst index b1a39ee17..c16a3e5d7 100644 --- a/docs/smtchecker.rst +++ b/docs/smtchecker.rst @@ -632,7 +632,8 @@ option ``--model-checker-solvers {all,cvc4,eld,smtlib2,z3}`` or the JSON option .. note:: z3 version 4.8.16 broke ABI compatibility with previous versions and cannot be used with solc <=0.8.13. If you are using z3 >=4.8.16 please use solc - >=0.8.14. + >=0.8.14, and conversely, only use older z3 with older solc releases. + We also recommend using the latest z3 release which is what SMTChecker also does. Since both BMC and CHC use ``z3``, and ``z3`` is available in a greater variety of environments, including in the browser, most users will almost never need to be diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index 8048eea58..de2724afa 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -664,7 +664,7 @@ introduced type and ``V`` has to be a built-in value type (the "underlying type" ``C.wrap`` is used to convert from the underlying type to the custom type. Similarly, the function ``C.unwrap`` is used to convert from the custom type to the underlying type. -The type ``C`` does not have any operators or bound member functions. In particular, even the +The type ``C`` does not have any operators or attached member functions. In particular, even the operator ``==`` is not defined. Explicit and implicit conversions to and from other types are disallowed. diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index 208829387..e622cd705 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -470,7 +470,7 @@ bool DeclarationTypeChecker::visit(UsingForDirective const& _usingFor) m_errorReporter.typeError( 4167_error, function->location(), - "Only file-level functions and library functions can be bound to a type in a \"using\" statement" + "Only file-level functions and library functions can be attached to a type in a \"using\" statement" ); } else diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index 167242b2c..8b6cd37eb 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -427,7 +427,7 @@ bool SyntaxChecker::visit(UsingForDirective const& _usingFor) m_errorReporter.syntaxError( 2854_error, _usingFor.location(), - "Can only globally bind functions to specific types." + "Can only globally attach functions to specific types." ); if (_usingFor.global() && m_currentContractKind) m_errorReporter.syntaxError( diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 2e81c6231..93558ff89 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -3167,7 +3167,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) if (auto funType = dynamic_cast(annotation.type)) { solAssert( - !funType->bound() || exprType->isImplicitlyConvertibleTo(*funType->selfType()), + !funType->hasBoundFirstArgument() || exprType->isImplicitlyConvertibleTo(*funType->selfType()), "Function \"" + memberName + "\" cannot be called on an object of type " + exprType->humanReadableName() + " (expected " + funType->selfType()->humanReadableName() + ")." ); @@ -3194,7 +3194,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) "Storage arrays with nested mappings do not support .push()." ); - if (!funType->bound()) + if (!funType->hasBoundFirstArgument()) if (auto typeType = dynamic_cast(exprType)) { auto contractType = dynamic_cast(typeType->actualType()); @@ -3810,13 +3810,13 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor) 4731_error, path->location(), fmt::format( - "The function \"{}\" does not have any parameters, and therefore cannot be bound to the type \"{}\".", + "The function \"{}\" does not have any parameters, and therefore cannot be attached to the type \"{}\".", joinHumanReadable(path->path(), "."), normalizedType ? normalizedType->toString(true /* withoutDataLocation */) : "*" ) ); - FunctionType const* functionType = dynamic_cast(*functionDefinition.type()).asBoundFunction(); + FunctionType const* functionType = dynamic_cast(*functionDefinition.type()).withBoundFirstArgument(); solAssert(functionType && functionType->selfType(), ""); BoolResult result = normalizedType->isImplicitlyConvertibleTo( *TypeProvider::withLocationIfReference(DataLocation::Storage, functionType->selfType()) @@ -3826,7 +3826,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor) 3100_error, path->location(), fmt::format( - "The function \"{}\" cannot be bound to the type \"{}\" because the type cannot " + "The function \"{}\" cannot be attached to the type \"{}\" because the type cannot " "be implicitly converted to the first argument of the function (\"{}\"){}", joinHumanReadable(path->path(), "."), usingForType->toString(true /* withoutDataLocation */), diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index f5680acbc..4b221141e 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -644,10 +644,9 @@ private: /** * Using for directive: * - * 1. `using LibraryName for T` attaches all functions from the library `LibraryName` to the type `T` + * 1. `using LibraryName for T` attaches all functions from the library `LibraryName` to the type `T`. * 2. `using LibraryName for *` attaches to all types. - * 3. `using {f1, f2, ..., fn} for T` attaches the functions `f1`, `f2`, ..., - * `fn`, respectively to `T`. + * 3. `using {f1, f2, ..., fn} for T` attaches the functions `f1`, `f2`, ..., `fn`, respectively to `T`. * * For version 3, T has to be implicitly convertible to the first parameter type of * all functions, and this is checked at the point of the using statement. For versions 1 and diff --git a/libsolidity/ast/TypeProvider.cpp b/libsolidity/ast/TypeProvider.cpp index 91d1da4be..9b90afdb2 100644 --- a/libsolidity/ast/TypeProvider.cpp +++ b/libsolidity/ast/TypeProvider.cpp @@ -450,7 +450,7 @@ FunctionType const* TypeProvider::function( ) { // Can only use this constructor for "arbitraryParameters". - solAssert(!_options.valueSet && !_options.gasSet && !_options.saltSet && !_options.bound); + solAssert(!_options.valueSet && !_options.gasSet && !_options.saltSet && !_options.hasBoundFirstArgument); return createAndGet( _parameterTypes, _returnParameterTypes, diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 5980f9366..f59a96577 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -305,7 +305,7 @@ MemberList const& Type::members(ASTNode const* _currentScope) const ""); MemberList::MemberMap members = nativeMembers(_currentScope); if (_currentScope) - members += boundFunctions(*this, *_currentScope); + members += attachedFunctions(*this, *_currentScope); m_members[_currentScope] = make_unique(std::move(members)); } return *m_members[_currentScope]; @@ -383,7 +383,7 @@ vector usingForDirectivesForType(Type const& _type, AS } -MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _scope) +MemberList::MemberMap Type::attachedFunctions(Type const& _type, ASTNode const& _scope) { MemberList::MemberMap members; @@ -395,13 +395,13 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _sc Type const* functionType = _function.libraryFunction() ? _function.typeViaContractName() : _function.type(); solAssert(functionType, ""); - FunctionType const* asBoundFunction = - dynamic_cast(*functionType).asBoundFunction(); - solAssert(asBoundFunction, ""); + FunctionType const* withBoundFirstArgument = + dynamic_cast(*functionType).withBoundFirstArgument(); + solAssert(withBoundFirstArgument, ""); - if (_type.isImplicitlyConvertibleTo(*asBoundFunction->selfType())) + if (_type.isImplicitlyConvertibleTo(*withBoundFirstArgument->selfType())) if (seenFunctions.insert(make_pair(*_name, &_function)).second) - members.emplace_back(&_function, asBoundFunction, *_name); + members.emplace_back(&_function, withBoundFirstArgument, *_name); }; for (UsingForDirective const* ufd: usingForDirectivesForType(_type, _scope)) @@ -1879,21 +1879,21 @@ MemberList::MemberMap ArrayType::nativeMembers(ASTNode const*) const strings{string()}, strings{string()}, FunctionType::Kind::ArrayPush - )->asBoundFunction()); + )->withBoundFirstArgument()); members.emplace_back("push", TypeProvider::function( TypePointers{thisAsPointer, baseType()}, TypePointers{}, strings{string(),string()}, strings{}, FunctionType::Kind::ArrayPush - )->asBoundFunction()); + )->withBoundFirstArgument()); members.emplace_back("pop", TypeProvider::function( TypePointers{thisAsPointer}, TypePointers{}, strings{string()}, strings{}, FunctionType::Kind::ArrayPop - )->asBoundFunction()); + )->withBoundFirstArgument()); } } return members; @@ -2952,7 +2952,7 @@ FunctionTypePointer FunctionType::newExpressionType(ContractDefinition const& _c vector FunctionType::parameterNames() const { - if (!bound()) + if (!hasBoundFirstArgument()) return m_parameterNames; return vector(m_parameterNames.cbegin() + 1, m_parameterNames.cend()); } @@ -2981,7 +2981,7 @@ TypePointers FunctionType::returnParameterTypesWithoutDynamicTypes() const TypePointers FunctionType::parameterTypes() const { - if (!bound()) + if (!hasBoundFirstArgument()) return m_parameterTypes; return TypePointers(m_parameterTypes.cbegin() + 1, m_parameterTypes.cend()); } @@ -3046,8 +3046,8 @@ string FunctionType::richIdentifier() const id += "value"; if (saltSet()) id += "salt"; - if (bound()) - id += "bound_to" + identifierList(selfType()); + if (hasBoundFirstArgument()) + id += "attached_to" + identifierList(selfType()); return id; } @@ -3081,11 +3081,11 @@ BoolResult FunctionType::isImplicitlyConvertibleTo(Type const& _convertTo) const FunctionType const& convertTo = dynamic_cast(_convertTo); // These two checks are duplicated in equalExcludingStateMutability, but are added here for error reporting. - if (convertTo.bound() != bound()) - return BoolResult::err("Bound functions can not be converted to non-bound functions."); + if (convertTo.hasBoundFirstArgument() != hasBoundFirstArgument()) + return BoolResult::err("Attached functions cannot be converted into unattached functions."); if (convertTo.kind() != kind()) - return BoolResult::err("Special functions can not be converted to function types."); + return BoolResult::err("Special functions cannot be converted to function types."); if (!equalExcludingStateMutability(convertTo)) return false; @@ -3122,10 +3122,10 @@ TypeResult FunctionType::binaryOperatorResult(Token _operator, Type const* _othe else if ( kind() == Kind::External && sizeOnStack() == 2 && - !bound() && + !hasBoundFirstArgument() && other.kind() == Kind::External && other.sizeOnStack() == 2 && - !other.bound() + !other.hasBoundFirstArgument() ) return commonType(this, _other); @@ -3210,7 +3210,7 @@ bool FunctionType::nameable() const { return (m_kind == Kind::Internal || m_kind == Kind::External) && - !bound() && + !hasBoundFirstArgument() && !takesArbitraryParameters() && !gasSet() && !valueSet() && @@ -3249,7 +3249,7 @@ vector> FunctionType::makeStackItems() const break; case Kind::ArrayPush: case Kind::ArrayPop: - solAssert(bound(), ""); + solAssert(hasBoundFirstArgument(), ""); slots = {}; break; default: @@ -3262,7 +3262,7 @@ vector> FunctionType::makeStackItems() const slots.emplace_back("value", TypeProvider::uint256()); if (saltSet()) slots.emplace_back("salt", TypeProvider::fixedBytes(32)); - if (bound()) + if (hasBoundFirstArgument()) slots.emplace_back("self", m_parameterTypes.front()); return slots; } @@ -3423,7 +3423,7 @@ TypeResult FunctionType::interfaceType(bool /*_inLibrary*/) const Type const* FunctionType::mobileType() const { - if (valueSet() || gasSet() || saltSet() || bound()) + if (valueSet() || gasSet() || saltSet() || hasBoundFirstArgument()) return nullptr; // return function without parameter names @@ -3444,8 +3444,8 @@ bool FunctionType::canTakeArguments( Type const* _selfType ) const { - solAssert(!bound() || _selfType, ""); - if (bound() && !_selfType->isImplicitlyConvertibleTo(*selfType())) + solAssert(!hasBoundFirstArgument() || _selfType, ""); + if (hasBoundFirstArgument() && !_selfType->isImplicitlyConvertibleTo(*selfType())) return false; TypePointers paramTypes = parameterTypes(); std::vector const paramNames = parameterNames(); @@ -3524,10 +3524,10 @@ bool FunctionType::equalExcludingStateMutability(FunctionType const& _other) con if (gasSet() != _other.gasSet() || valueSet() != _other.valueSet() || saltSet() != _other.saltSet()) return false; - if (bound() != _other.bound()) + if (hasBoundFirstArgument() != _other.hasBoundFirstArgument()) return false; - solAssert(!bound() || *selfType() == *_other.selfType(), ""); + solAssert(!hasBoundFirstArgument() || *selfType() == *_other.selfType(), ""); return true; } @@ -3648,14 +3648,14 @@ Type const* FunctionType::copyAndSetCallOptions(bool _setGas, bool _setValue, bo ); } -FunctionTypePointer FunctionType::asBoundFunction() const +FunctionTypePointer FunctionType::withBoundFirstArgument() const { solAssert(!m_parameterTypes.empty(), ""); solAssert(!gasSet(), ""); solAssert(!valueSet(), ""); solAssert(!saltSet(), ""); Options options = Options::fromFunctionType(*this); - options.bound = true; + options.hasBoundFirstArgument = true; return TypeProvider::function( m_parameterTypes, m_returnParameterTypes, @@ -3710,7 +3710,7 @@ FunctionTypePointer FunctionType::asExternallyCallableFunction(bool _inLibrary) Type const* FunctionType::selfType() const { - solAssert(bound(), "Function is not bound."); + solAssert(hasBoundFirstArgument(), "Function is not attached to a type."); solAssert(m_parameterTypes.size() > 0, "Function has no self type."); return m_parameterTypes.at(0); } diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 735bd6902..2f9277808 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -326,7 +326,7 @@ public: /// given location. virtual bool dataStoredIn(DataLocation) const { return false; } - /// Returns the list of all members of this type. Default implementation: no members apart from bound. + /// Returns the list of all members of this type. Default implementation: no members apart from attached functions. /// @param _currentScope scope in which the members are accessed. MemberList const& members(ASTNode const* _currentScope) const; /// Convenience method, returns the type of the given named member or an empty pointer if no such member exists. @@ -379,11 +379,11 @@ public: private: /// @returns a member list containing all members added to this type by `using for` directives. - static MemberList::MemberMap boundFunctions(Type const& _type, ASTNode const& _scope); + static MemberList::MemberMap attachedFunctions(Type const& _type, ASTNode const& _scope); protected: /// @returns the members native to this type depending on the given context. This function - /// is used (in conjunction with boundFunctions to fill m_members below. + /// is used (in conjunction with attachedFunctions to fill m_members below. virtual MemberList::MemberMap nativeMembers(ASTNode const* /*_currentScope*/) const { return MemberList::MemberMap(); @@ -802,14 +802,14 @@ public: /// Constructor for a byte array ("bytes") and string. explicit ArrayType(DataLocation _location, bool _isString = false); - /// Constructor for a dynamically sized array type ("type[]") + /// Constructor for a dynamically sized array type ("[]") ArrayType(DataLocation _location, Type const* _baseType): ReferenceType(_location), m_baseType(copyForLocationIfReference(_baseType)) { } - /// Constructor for a fixed-size array type ("type[20]") + /// Constructor for a fixed-size array type ("[]") ArrayType(DataLocation _location, Type const* _baseType, u256 _length): ReferenceType(_location), m_baseType(copyForLocationIfReference(_baseType)), @@ -1272,7 +1272,7 @@ public: bool saltSet = false; /// true iff the function is called as arg1.fun(arg2, ..., argn). /// This is achieved through the "using for" directive. - bool bound = false; + bool hasBoundFirstArgument = false; static Options withArbitraryParameters() { @@ -1287,7 +1287,7 @@ public: result.gasSet = _type.gasSet(); result.valueSet = _type.valueSet(); result.saltSet = _type.saltSet(); - result.bound = _type.bound(); + result.hasBoundFirstArgument = _type.hasBoundFirstArgument(); return result; } }; @@ -1322,7 +1322,7 @@ public: ) { // In this constructor, only the "arbitrary Parameters" option should be used. - solAssert(!bound() && !gasSet() && !valueSet() && !saltSet()); + solAssert(!hasBoundFirstArgument() && !gasSet() && !valueSet() && !saltSet()); } /// Detailed constructor, use with care. @@ -1354,8 +1354,8 @@ public: "Return parameter names list must match return parameter types list!" ); solAssert( - !bound() || !m_parameterTypes.empty(), - "Attempted construction of bound function without self type" + !hasBoundFirstArgument() || !m_parameterTypes.empty(), + "Attempted construction of attached function without self type" ); } @@ -1372,7 +1372,7 @@ public: /// storage pointers) are replaced by InaccessibleDynamicType instances. TypePointers returnParameterTypesWithoutDynamicTypes() const; std::vector const& returnParameterNames() const { return m_returnParameterNames; } - /// @returns the "self" parameter type for a bound function + /// @returns the "self" parameter type for an attached function Type const* selfType() const; std::string richIdentifier() const override; @@ -1406,8 +1406,8 @@ public: /// @returns true if this function can take the given arguments (possibly /// after implicit conversion). - /// @param _selfType if the function is bound, this has to be supplied and is the type of the - /// expression the function is called on. + /// @param _selfType if the function is attached as a member function, this has to be supplied + /// and is the type of the expression the function is called on. bool canTakeArguments( FuncCallArguments const& _arguments, Type const* _selfType = nullptr @@ -1471,20 +1471,20 @@ public: bool gasSet() const { return m_options.gasSet; } bool valueSet() const { return m_options.valueSet; } bool saltSet() const { return m_options.saltSet; } - bool bound() const { return m_options.bound; } + bool hasBoundFirstArgument() const { return m_options.hasBoundFirstArgument; } /// @returns a copy of this type, where gas or value are set manually. This will never set one /// of the parameters to false. Type const* copyAndSetCallOptions(bool _setGas, bool _setValue, bool _setSalt) const; - /// @returns a copy of this function type with the `bound` flag set to true. + /// @returns a copy of this function type with the `hasBoundFirstArgument` flag set to true. /// Should only be called on library functions. - FunctionTypePointer asBoundFunction() const; + FunctionTypePointer withBoundFirstArgument() const; /// @returns a copy of this function type where the location of reference types is changed /// from CallData to Memory. This is the type that would be used when the function is /// called externally, as opposed to the parameter types that are available inside the function body. - /// Also supports variants to be used for library or bound calls. + /// Also supports variants to be used for library or attached function calls. /// @param _inLibrary if true, uses DelegateCall as location. FunctionTypePointer asExternallyCallableFunction(bool _inLibrary) const; diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 461de5648..b26825c77 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -612,7 +612,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) else { FunctionType const& function = *functionType; - if (function.bound()) + if (function.hasBoundFirstArgument()) solAssert( function.kind() == FunctionType::Kind::DelegateCall || function.kind() == FunctionType::Kind::Internal || @@ -637,7 +637,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) bool shortcutTaken = false; if (auto identifier = dynamic_cast(&_functionCall.expression())) { - solAssert(!function.bound(), ""); + solAssert(!function.hasBoundFirstArgument(), ""); if (auto functionDef = dynamic_cast(identifier->annotation().referencedDeclaration)) { // Do not directly visit the identifier, because this way, we can avoid @@ -657,7 +657,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } unsigned parameterSize = CompilerUtils::sizeOnStack(function.parameterTypes()); - if (function.bound()) + if (function.hasBoundFirstArgument()) { // stack: arg2, ..., argn, label, arg1 unsigned depth = parameterSize + 1; @@ -906,7 +906,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) argumentType && functionType->kind() == FunctionType::Kind::External && argumentType->kind() == FunctionType::Kind::External && - !argumentType->bound(), + !argumentType->hasBoundFirstArgument(), "" ); @@ -1029,7 +1029,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::ArrayPush: { - solAssert(function.bound(), ""); + solAssert(function.hasBoundFirstArgument(), ""); _functionCall.expression().accept(*this); if (function.parameterTypes().size() == 0) @@ -1095,7 +1095,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) case FunctionType::Kind::ArrayPop: { _functionCall.expression().accept(*this); - solAssert(function.bound(), ""); + solAssert(function.hasBoundFirstArgument(), ""); solAssert(function.parameterTypes().empty(), ""); ArrayType const* arrayType = dynamic_cast(function.selfType()); solAssert(arrayType && arrayType->dataStoredIn(DataLocation::Storage), ""); @@ -1476,10 +1476,10 @@ bool ExpressionCompiler::visit(NewExpression const&) bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) { CompilerContext::LocationSetter locationSetter(m_context, _memberAccess); - // Check whether the member is a bound function. + // Check whether the member is an attached function. ASTString const& member = _memberAccess.memberName(); if (auto funType = dynamic_cast(_memberAccess.annotation().type)) - if (funType->bound()) + if (funType->hasBoundFirstArgument()) { acceptAndConvert(_memberAccess.expression(), *funType->selfType(), true); if (funType->kind() == FunctionType::Kind::Internal) @@ -2570,14 +2570,14 @@ void ExpressionCompiler::appendExternalFunctionCall( // function identifier [unless bare] // contract address - unsigned selfSize = _functionType.bound() ? _functionType.selfType()->sizeOnStack() : 0; + unsigned selfSize = _functionType.hasBoundFirstArgument() ? _functionType.selfType()->sizeOnStack() : 0; unsigned gasValueSize = (_functionType.gasSet() ? 1u : 0u) + (_functionType.valueSet() ? 1u : 0u); unsigned contractStackPos = m_context.currentToBaseStackOffset(1 + gasValueSize + selfSize + (_functionType.isBareCall() ? 0 : 1)); unsigned gasStackPos = m_context.currentToBaseStackOffset(gasValueSize); unsigned valueStackPos = m_context.currentToBaseStackOffset(1); // move self object to top - if (_functionType.bound()) + if (_functionType.hasBoundFirstArgument()) utils().moveToStackTop(gasValueSize, _functionType.selfType()->sizeOnStack()); auto funKind = _functionType.kind(); @@ -2605,7 +2605,7 @@ void ExpressionCompiler::appendExternalFunctionCall( // Evaluate arguments. TypePointers argumentTypes; TypePointers parameterTypes = _functionType.parameterTypes(); - if (_functionType.bound()) + if (_functionType.hasBoundFirstArgument()) { argumentTypes.push_back(_functionType.selfType()); parameterTypes.insert(parameterTypes.begin(), _functionType.selfType()); diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp index 2708d319d..8f20cd992 100644 --- a/libsolidity/codegen/LValue.cpp +++ b/libsolidity/codegen/LValue.cpp @@ -321,7 +321,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc _sourceType.isImplicitlyConvertibleTo(*m_dataType), "function item stored but target is not implicitly convertible to source" ); - solAssert(!fun->bound(), ""); + solAssert(!fun->hasBoundFirstArgument(), ""); if (fun->kind() == FunctionType::Kind::External) { solAssert(fun->sizeOnStack() == 2, ""); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 30575930c..1ec64b548 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -953,7 +953,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) solAssert(!functionType->takesArbitraryParameters()); vector args; - if (functionType->bound()) + if (functionType->hasBoundFirstArgument()) args += IRVariable(_functionCall.expression()).part("self").stackSlots(); for (size_t i = 0; i < arguments.size(); ++i) @@ -1024,7 +1024,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) solAssert( IRVariable(arg).type() == *functionType && functionType->kind() == FunctionType::Kind::External && - !functionType->bound(), + !functionType->hasBoundFirstArgument(), "" ); define(indexedArgs.emplace_back(m_context.newYulVariable(), *TypeProvider::fixedBytes(32))) << @@ -1353,7 +1353,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) } case FunctionType::Kind::ArrayPop: { - solAssert(functionType->bound()); + solAssert(functionType->hasBoundFirstArgument()); solAssert(functionType->parameterTypes().empty()); ArrayType const* arrayType = dynamic_cast(functionType->selfType()); solAssert(arrayType); @@ -1557,7 +1557,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) solAssert(!_functionCall.annotation().tryCall); solAssert(!functionType->valueSet()); solAssert(!functionType->gasSet()); - solAssert(!functionType->bound()); + solAssert(!functionType->hasBoundFirstArgument()); static map> precompiles = { {FunctionType::Kind::ECRecover, std::make_tuple(1, 0)}, @@ -1623,7 +1623,7 @@ void IRGeneratorForStatements::endVisit(FunctionCallOptions const& _options) setLocation(_options); FunctionType const& previousType = dynamic_cast(*_options.expression().annotation().type); - solUnimplementedAssert(!previousType.bound()); + solUnimplementedAssert(!previousType.hasBoundFirstArgument()); // Copy over existing values. for (auto const& item: previousType.stackItems()) @@ -1668,7 +1668,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) auto memberFunctionType = dynamic_cast(_memberAccess.annotation().type); Type::Category objectCategory = _memberAccess.expression().annotation().type->category(); - if (memberFunctionType && memberFunctionType->bound()) + if (memberFunctionType && memberFunctionType->hasBoundFirstArgument()) { define(IRVariable(_memberAccess).part("self"), _memberAccess.expression()); solAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Static); @@ -2506,7 +2506,7 @@ void IRGeneratorForStatements::appendExternalFunctionCall( TypePointers parameterTypes = funType.parameterTypes(); TypePointers argumentTypes; vector argumentStrings; - if (funType.bound()) + if (funType.hasBoundFirstArgument()) { parameterTypes.insert(parameterTypes.begin(), funType.selfType()); argumentTypes.emplace_back(funType.selfType()); @@ -2655,7 +2655,7 @@ void IRGeneratorForStatements::appendBareCall( { FunctionType const& funType = dynamic_cast(type(_functionCall.expression())); solAssert( - !funType.bound() && + !funType.hasBoundFirstArgument() && !funType.takesArbitraryParameters() && _arguments.size() == 1 && funType.parameterTypes().size() == 1, "" diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index eea459737..25789a3b6 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -3120,12 +3120,12 @@ vector SMTEncoder::symbolicArguments(FunctionCall const& _f vector> arguments = _funCall.sortedArguments(); auto functionParams = funDef->parameters(); unsigned firstParam = 0; - if (funType->bound()) + if (funType->hasBoundFirstArgument()) { calledExpr = innermostTuple(*calledExpr); - auto const& boundFunction = dynamic_cast(calledExpr); - solAssert(boundFunction, ""); - args.push_back(expr(boundFunction->expression(), functionParams.front()->type())); + auto const& attachedFunction = dynamic_cast(calledExpr); + solAssert(attachedFunction, ""); + args.push_back(expr(attachedFunction->expression(), functionParams.front()->type())); firstParam = 1; } diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index 16b87be33..2ba491a0b 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -401,7 +401,7 @@ protected: void createReturnedExpressions(FunctionCall const& _funCall, ContractDefinition const* _contextContract); /// @returns the symbolic arguments for a function call, - /// taking into account bound functions and + /// taking into account attached functions and /// type conversion. std::vector symbolicArguments(FunctionCall const& _funCall, ContractDefinition const* _contextContract); diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index 1d5519b57..59ba7c8f0 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -86,6 +87,8 @@ void DataFlowAnalyzer::operator()(ExpressionStatement& _statement) cxx20::erase_if(m_state.environment.memory, mapTuple([&](auto&& key, auto&& /* value */) { return !m_knowledgeBase.knownToBeDifferentByAtLeast32(vars->first, key); })); + // TODO erase keccak knowledge, but in a more clever way + m_state.environment.keccak = {}; m_state.environment.memory[vars->first] = vars->second; return; } @@ -127,7 +130,6 @@ void DataFlowAnalyzer::operator()(If& _if) Environment preEnvironment = m_state.environment; ASTModifier::operator()(_if); - joinKnowledge(preEnvironment); clearValues(assignedVariableNames(_if.body)); @@ -223,7 +225,7 @@ void DataFlowAnalyzer::operator()(Block& _block) optional DataFlowAnalyzer::storageValue(YulString _key) const { - if (YulString const* value = util::valueOrNullptr(m_state.environment.storage, _key)) + if (YulString const* value = valueOrNullptr(m_state.environment.storage, _key)) return *value; else return nullopt; @@ -231,7 +233,15 @@ optional DataFlowAnalyzer::storageValue(YulString _key) const optional DataFlowAnalyzer::memoryValue(YulString _key) const { - if (YulString const* value = util::valueOrNullptr(m_state.environment.memory, _key)) + if (YulString const* value = valueOrNullptr(m_state.environment.memory, _key)) + return *value; + else + return nullopt; +} + +optional DataFlowAnalyzer::keccakValue(YulString _start, YulString _length) const +{ + if (YulString const* value = valueOrNullptr(m_state.environment.keccak, make_pair(_start, _length))) return *value; else return nullopt; @@ -271,6 +281,9 @@ void DataFlowAnalyzer::handleAssignment(set const& _variables, Expres // assignment to slot denoted by "name" m_state.environment.memory.erase(name); // assignment to slot contents denoted by "name" + cxx20::erase_if(m_state.environment.keccak, [&name](auto&& _item) { + return _item.first.first == name || _item.first.second == name || _item.second == name; + }); cxx20::erase_if(m_state.environment.memory, mapTuple([&name](auto&& /* key */, auto&& value) { return value == name; })); } } @@ -287,6 +300,8 @@ void DataFlowAnalyzer::handleAssignment(set const& _variables, Expres m_state.environment.memory[*key] = variable; else if (auto key = isSimpleLoad(StoreLoadLocation::Storage, *_value)) m_state.environment.storage[*key] = variable; + else if (auto arguments = isKeccak(*_value)) + m_state.environment.keccak[*arguments] = variable; } } } @@ -314,7 +329,7 @@ void DataFlowAnalyzer::clearValues(set _variables) // let a := 1 // let b := a // let c := b - // let a := 2 + // a := 2 // add(b, c) // In the last line, we can replace c by b, but not b by a. // @@ -329,6 +344,12 @@ void DataFlowAnalyzer::clearValues(set _variables) }); cxx20::erase_if(m_state.environment.storage, eraseCondition); cxx20::erase_if(m_state.environment.memory, eraseCondition); + cxx20::erase_if(m_state.environment.keccak, [&_variables](auto&& _item) { + return + _variables.count(_item.first.first) || + _variables.count(_item.first.second) || + _variables.count(_item.second); + }); // Also clear variables that reference variables to be cleared. for (auto const& variableToClear: _variables) @@ -357,7 +378,10 @@ void DataFlowAnalyzer::clearKnowledgeIfInvalidated(Block const& _block) if (sideEffects.invalidatesStorage()) m_state.environment.storage.clear(); if (sideEffects.invalidatesMemory()) + { m_state.environment.memory.clear(); + m_state.environment.keccak.clear(); + } } void DataFlowAnalyzer::clearKnowledgeIfInvalidated(Expression const& _expr) @@ -368,7 +392,10 @@ void DataFlowAnalyzer::clearKnowledgeIfInvalidated(Expression const& _expr) if (sideEffects.invalidatesStorage()) m_state.environment.storage.clear(); if (sideEffects.invalidatesMemory()) + { m_state.environment.memory.clear(); + m_state.environment.keccak.clear(); + } } bool DataFlowAnalyzer::inScope(YulString _variableName) const @@ -416,12 +443,26 @@ std::optional DataFlowAnalyzer::isSimpleLoad( return {}; } +optional> DataFlowAnalyzer::isKeccak(Expression const& _expression) const +{ + if (FunctionCall const* funCall = get_if(&_expression)) + if (funCall->functionName.name == m_dialect.hashFunction({})) + if (Identifier const* start = std::get_if(&funCall->arguments.at(0))) + if (Identifier const* length = std::get_if(&funCall->arguments.at(1))) + return make_pair(start->name, length->name); + return nullopt; +} + void DataFlowAnalyzer::joinKnowledge(Environment const& _olderEnvironment) { if (!m_analyzeStores) return; joinKnowledgeHelper(m_state.environment.storage, _olderEnvironment.storage); joinKnowledgeHelper(m_state.environment.memory, _olderEnvironment.memory); + cxx20::erase_if(m_state.environment.keccak, mapTuple([&_olderEnvironment](auto&& key, auto&& currentValue) { + YulString const* oldValue = valueOrNullptr(_olderEnvironment.keccak, key); + return !oldValue || *oldValue != currentValue; + })); } void DataFlowAnalyzer::joinKnowledgeHelper( @@ -434,7 +475,7 @@ void DataFlowAnalyzer::joinKnowledgeHelper( // of m_state.environment.memory and thus any overlapping write would have cleared the keys // that are not known to be different inside m_state.environment.memory already. cxx20::erase_if(_this, mapTuple([&_older](auto&& key, auto&& currentValue){ - YulString const* oldValue = util::valueOrNullptr(_older, key); + YulString const* oldValue = valueOrNullptr(_older, key); return !oldValue || *oldValue != currentValue; })); } diff --git a/libyul/optimiser/DataFlowAnalyzer.h b/libyul/optimiser/DataFlowAnalyzer.h index ef8d49a87..b449357e6 100644 --- a/libyul/optimiser/DataFlowAnalyzer.h +++ b/libyul/optimiser/DataFlowAnalyzer.h @@ -108,6 +108,7 @@ public: std::map const& allValues() const { return m_state.value; } std::optional storageValue(YulString _key) const; std::optional memoryValue(YulString _key) const; + std::optional keccakValue(YulString _start, YulString _length) const; protected: /// Registers the assignment. @@ -157,6 +158,10 @@ protected: Expression const& _expression ) const; + /// Checks if the expression is keccak256(s, l) + /// where s and l are variables and returns these variables in that case. + std::optional> isKeccak(Expression const& _expression) const; + Dialect const& m_dialect; /// Side-effects of user-defined functions. Worst-case side-effects are assumed /// if this is not provided or the function is not found. @@ -167,6 +172,8 @@ private: { std::unordered_map storage; std::unordered_map memory; + /// If keccak[s, l] = y then y := keccak256(s, l) occurs in the code. + std::map, YulString> keccak; }; struct State { diff --git a/libyul/optimiser/LoadResolver.cpp b/libyul/optimiser/LoadResolver.cpp index abcfbaabb..ce0ce730e 100644 --- a/libyul/optimiser/LoadResolver.cpp +++ b/libyul/optimiser/LoadResolver.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -58,15 +59,23 @@ void LoadResolver::visit(Expression& _e) if (FunctionCall const* funCall = std::get_if(&_e)) { - for (auto location: { StoreLoadLocation::Memory, StoreLoadLocation::Storage }) - if (funCall->functionName.name == m_loadFunctionName[static_cast(location)]) - { - tryResolve(_e, location, funCall->arguments); - break; - } - - if (!m_containsMSize && funCall->functionName.name == m_dialect.hashFunction({})) + if (funCall->functionName.name == m_loadFunctionName[static_cast(StoreLoadLocation::Memory)]) + tryResolve(_e, StoreLoadLocation::Memory, funCall->arguments); + else if (funCall->functionName.name == m_loadFunctionName[static_cast(StoreLoadLocation::Storage)]) + tryResolve(_e, StoreLoadLocation::Storage, funCall->arguments); + else if (!m_containsMSize && funCall->functionName.name == m_dialect.hashFunction({})) + { + Identifier const* start = get_if(&funCall->arguments.at(0)); + Identifier const* length = get_if(&funCall->arguments.at(1)); + if (start && length) + if (auto const& value = keccakValue(start->name, length->name)) + if (inScope(*value)) + { + _e = Identifier{debugDataOf(_e), *value}; + return; + } tryEvaluateKeccak(_e, funCall->arguments); + } } } diff --git a/test/externalTests/chainlink.sh b/test/externalTests/chainlink.sh index 9f50e1486..249a1254c 100755 --- a/test/externalTests/chainlink.sh +++ b/test/externalTests/chainlink.sh @@ -64,7 +64,7 @@ function chainlink_test # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables # them for other presets but that's fine - we want same code run for benchmarks to be comparable. - # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/2115). + # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3365). sed -i "s|\(it\)\(('reverts'\)|\1.skip\2|g" test/v0.6/BasicConsumer.test.ts sed -i "s|\(it\)\(('has a reasonable gas cost \[ @skip-coverage \]'\)|\1.skip\2|g" test/v0.6/BasicConsumer.test.ts sed -i "s|\(describe\)\(('#add[^']*'\)|\1.skip\2|g" test/v0.6/Chainlink.test.ts @@ -78,7 +78,7 @@ function chainlink_test sed -i "s|\(context\)\(('when permissions are not set'\)|\1.skip\2|g" test/v0.8/KeeperRegistry.test.ts # In some cases Hardhat does not detect revert reasons properly via IR. - # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/2453 gets fixed. + # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed. sed -i "s|\(it\)\(('does not allow the specified address to start new rounds'\)|\1.skip\2|g" test/v0.6/FluxAggregator.test.ts sed -i "s|\(describe\)\(('when called by a stranger'\)|\1.skip\2|g" test/v0.6/FluxAggregator.test.ts sed -i "s|\(describe\)\(('if the access control is turned on'\)|\1.skip\2|g" test/v0.*/Flags.test.ts diff --git a/test/externalTests/elementfi.sh b/test/externalTests/elementfi.sh index 4901c6bf1..b667a4bbc 100755 --- a/test/externalTests/elementfi.sh +++ b/test/externalTests/elementfi.sh @@ -87,13 +87,9 @@ function elementfi_test sed -i 's|bytes32(uint256(pool))|bytes32(uint256(uint160(pool)))|g' vault/PoolRegistry.sol popd - # The test suite uses forked Mainnet and an expiration period that's too short. - # TODO: Remove when https://github.com/element-fi/elf-contracts/issues/243 is fixed. - sed -i 's|^\s*require(_expiration - block\.timestamp < _unitSeconds);\s*$||g' contracts/ConvergentCurvePool.sol - # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables # them for other presets but that's fine - we want same code run for benchmarks to be comparable. - # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/2115). + # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3365). sed -i 's|it(\("fails to withdraw more shares than in balance"\)|it.skip(\1|g' test/compoundAssetProxyTest.ts sed -i 's|it(\("should prevent withdrawal of Principal Tokens and Interest Tokens before the tranche expires "\)|it.skip(\1|g' test/trancheTest.ts sed -i 's|it(\("should prevent withdrawal of more Principal Tokens and Interest Tokens than the user has"\)|it.skip(\1|g' test/trancheTest.ts diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index 5cc2a574d..77395160d 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -69,9 +69,8 @@ function ens_test neutralize_packaged_contracts # In some cases Hardhat does not detect revert reasons properly via IR. - # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/2115 gets fixed. + # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed. sed -i "s|it\(('Does not allow wrapping a name you do not own',\)|it.skip\1|g" test/wrapper/NameWrapper.js - # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/2453 gets fixed. sed -i "s|it\(('can set fuses and then burn ability to burn fuses',\)|it.skip\1|g" test/wrapper/NameWrapper.js sed -i "s|it\(('can set fuses and burn canSetResolver and canSetTTL',\)|it.skip\1|g" test/wrapper/NameWrapper.js sed -i "s|it\(('Cannot be called if CANNOT_TRANSFER is burned\.',\)|it.skip\1|g" test/wrapper/NameWrapper.js diff --git a/test/externalTests/euler.sh b/test/externalTests/euler.sh index e26b89248..78e89d147 100755 --- a/test/externalTests/euler.sh +++ b/test/externalTests/euler.sh @@ -63,7 +63,7 @@ function euler_test # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables # them for other presets but that's fine - we want same code run for benchmarks to be comparable. - # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/2453 gets fixed. + # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed. sed -i "/expectError: 'JUNK_UPGRADE_TEST_FAILURE'/d" test/moduleUpgrade.js sed -i "/et\.expect(errMsg)\.to\.contain('e\/collateral-violation');/d" test/flashLoanNative.js @@ -73,10 +73,6 @@ function euler_test force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" force_hardhat_unlimited_contract_size "$config_file" npm install - - # TODO: Remove this when https://github.com/Uniswap/v3-periphery/issues/313 gets fixed. - npm install @uniswap/v3-periphery@1.4.1 - replace_version_pragmas neutralize_packaged_contracts diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 81e5180c6..a6ded27e1 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -71,9 +71,9 @@ function gnosis_safe_test # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables # them for other presets but that's fine - we want same code run for benchmarks to be comparable. - # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/2115). + # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3365). sed -i "s|\(it\)\(('should not allow to call setup on singleton'\)|\1.skip\2|g" test/core/GnosisSafe.Setup.spec.ts - # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/2453 gets fixed. + # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed. sed -i 's|\(it\)\(("changes the expected storage slot without touching the most important ones"\)|\1.skip\2|g' test/libraries/SignMessageLib.spec.ts sed -i "s|\(it\)\(('can be used only via DELEGATECALL opcode'\)|\1.skip\2|g" test/libraries/SignMessageLib.spec.ts sed -i 's|\(describe\)\(("Upgrade from Safe 1.1.1"\)|\1.skip\2|g' test/migration/UpgradeFromSafe111.spec.ts @@ -82,7 +82,7 @@ function gnosis_safe_test # TODO: Remove this when Gnosis merges https://github.com/gnosis/safe-contracts/pull/394 sed -i "s|\(function isValidSignature(bytes \)calldata\( _data, bytes \)calldata\( _signature)\)|\1memory\2memory\3|g" contracts/handler/CompatibilityFallbackHandler.sol - # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/2453 gets fixed. + # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed. sed -i "s|it\(('should enforce delegatecall'\)|it.skip\1|g" test/accessors/SimulateTxAccessor.spec.ts sed -i "s|it\(('can only be called from Safe itself'\)|it.skip\1|g" test/libraries/Migration.spec.ts sed -i "s|it\(('should enforce delegatecall to MultiSend'\)|it.skip\1|g" test/libraries/MultiSend.spec.ts @@ -122,10 +122,6 @@ function gnosis_safe_test # TODO: Remove when https://github.com/safe-global/safe-contracts/issues/436 is resolved. npx npm install @nomiclabs/hardhat-ethers@2.1.0 - # Hardhat 2.9.5 introduced a bug with handling padded arguments to getStorageAt(). - # TODO: Remove when https://github.com/NomicFoundation/hardhat/issues/2709 is fixed. - npx npm install hardhat@2.9.4 - replace_version_pragmas [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc/dist" diff --git a/test/externalTests/gp2.sh b/test/externalTests/gp2.sh index ad75f83bd..9e9ee72af 100755 --- a/test/externalTests/gp2.sh +++ b/test/externalTests/gp2.sh @@ -99,7 +99,7 @@ function gp2_test # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables # them for other presets but that's fine - we want same code run for benchmarks to be comparable. - # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/2115). + # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3365). sed -i 's|it\(("should revert when encoding invalid flags"\)|it.skip\1|g' test/GPv2Trade.test.ts replace_version_pragmas diff --git a/test/externalTests/perpetual-pools.sh b/test/externalTests/perpetual-pools.sh index a389e833f..18fb308af 100755 --- a/test/externalTests/perpetual-pools.sh +++ b/test/externalTests/perpetual-pools.sh @@ -61,7 +61,7 @@ function perpetual_pools_test # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables # them for other presets but that's fine - we want same code run for benchmarks to be comparable. - # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/2115). + # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3365). sed -i 's|\(it\)\(("Should not allow commits that are too large"\)|\1.skip\2|g' test/PoolCommitter/commit.spec.ts sed -i 's|\(it\)\(("Should not allow for too many commitments (that bring amount over a user'\''s balance)"\)|\1.skip\2|g' test/PoolCommitter/commit.spec.ts diff --git a/test/externalTests/pool-together.sh b/test/externalTests/pool-together.sh index a3461a6b0..14c7853f4 100755 --- a/test/externalTests/pool-together.sh +++ b/test/externalTests/pool-together.sh @@ -59,7 +59,7 @@ function pool_together_test setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" download_project "$repo" "$ref_type" "$ref" "$DIR" - # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/2453 gets fixed. + # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed. sed -i "s|it\(('should fail to return value if value passed does not fit in [0-9]\+ bits'\)|it.skip\1|g" test/libraries/ExtendedSafeCast.test.ts sed -i "s|it\(('should require an rng to be requested'\)|it.skip\1|g" test/DrawBeacon.test.ts @@ -69,6 +69,9 @@ function pool_together_test force_hardhat_compiler_settings "$config_file" "$(first_word "$SELECTED_PRESETS")" "$config_var" yarn install + # TODO: Remove this when https://github.com/pooltogether/v4-core/issues/287 gets fixed. + npm install @pooltogether/pooltogether-rng-contracts@1.4.0 + # These come with already compiled artifacts. We want them recompiled with latest compiler. rm -r node_modules/@pooltogether/yield-source-interface/artifacts/ rm -r node_modules/@pooltogether/uniform-random-number/artifacts/ diff --git a/test/externalTests/prb-math.sh b/test/externalTests/prb-math.sh index 98a73627f..78a39519e 100755 --- a/test/externalTests/prb-math.sh +++ b/test/externalTests/prb-math.sh @@ -71,7 +71,7 @@ function prb_math_test # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables # them for other presets but that's fine - we want same code run for benchmarks to be comparable. - # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/2115). + # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3365). pushd test/contracts/prbMathUd60x18/pure/ sed -i 's|context(\("when the sum overflows"\)|context.skip(\1|g' add.test.ts sed -i 's|context(\("when the sum does not overflow"\)|context.skip(\1|g' add.test.ts diff --git a/test/externalTests/trident.sh b/test/externalTests/trident.sh index 401446f99..b5d48b500 100755 --- a/test/externalTests/trident.sh +++ b/test/externalTests/trident.sh @@ -89,7 +89,7 @@ function trident_test sed -i 's|IStrategy(0)|IStrategy(address(0))|g' contracts/flat/BentoBoxV1Flat.sol find contracts -name "*.sol" -exec sed -i -e 's/^\(\s*\)\(assembly\)/\1\/\/\/ @solidity memory-safe-assembly\n\1\2/' '{}' \; - # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/2453 gets fixed. + # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed. sed -i 's|it\(("Reverts on direct deployment via factory"\)|it.skip\1|g' test/MasterDeployer.test.ts # @sushiswap/core package contains contracts that get built with 0.6.12 and fail our compiler diff --git a/test/externalTests/uniswap.sh b/test/externalTests/uniswap.sh index 5da068df8..8b07aee84 100755 --- a/test/externalTests/uniswap.sh +++ b/test/externalTests/uniswap.sh @@ -61,7 +61,7 @@ function uniswap_test # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables # them for other presets but that's fine - we want same code run for benchmarks to be comparable. - # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/2115 gets fixed. + # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed. sed -i "s|it\(('underpay zero for one and exact in',\)|it.skip\1|g" test/UniswapV3Pool.spec.ts sed -i "s|it\(('pay in the wrong token zero for one and exact in',\)|it.skip\1|g" test/UniswapV3Pool.spec.ts sed -i "s|it\(('underpay zero for one and exact out',\)|it.skip\1|g" test/UniswapV3Pool.spec.ts diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index fafa23ffb..27198a8f0 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -63,7 +63,7 @@ function zeppelin_test # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables # them for other presets but that's fine - we want same code run for benchmarks to be comparable. - # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/2115). + # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3365). pushd test/utils/ sed -i "s|it(\('reverts \)|it.skip(\1|g" math/SafeMath.test.js sed -i "s|it(\('reverts \)|it.skip(\1|g" math/SignedSafeMath.test.js @@ -75,7 +75,7 @@ function zeppelin_test # In some cases Hardhat does not detect revert reasons properly via IR. - # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/2453 gets fixed. + # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed. sed -i "s|it(\('reverts if the current value is 0'\)|it.skip(\1|g" test/utils/Counters.test.js sed -i "s|it(\('prevent unauthorized maintenance'\)|it.skip(\1|g" test/governance/TimelockController.test.js sed -i "s|it(\('cannot cancel invalid operation'\)|it.skip(\1|g" test/governance/TimelockController.test.js @@ -123,7 +123,7 @@ function zeppelin_test - # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/2115 gets fixed. + # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed. sed -i "s|describe\(('Polygon-Child'\)|describe.skip\1|g" test/crosschain/CrossChainEnabled.test.js sed -i "s|it(\('revert with invalid multi proof #2'\)|it.skip(\1|g" test/utils/cryptography/MerkleProof.test.js sed -i "s|describe(\('to a receiver contract that panics'\)|describe.skip(\1|g" test/token/ERC721/ERC721.behavior.js diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index beb622241..2f0d1a5d0 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -2811,7 +2811,7 @@ BOOST_AUTO_TEST_CASE(return_external_function_type) ); } -// TODO: store bound internal library functions +// TODO: store attached internal library functions BOOST_AUTO_TEST_CASE(shift_bytes) { diff --git a/test/libsolidity/semanticTests/array/reusing_memory.sol b/test/libsolidity/semanticTests/array/reusing_memory.sol index fa8e84931..d4dafdb73 100644 --- a/test/libsolidity/semanticTests/array/reusing_memory.sol +++ b/test/libsolidity/semanticTests/array/reusing_memory.sol @@ -24,6 +24,6 @@ contract Main { } // ---- // f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1 -// gas irOptimized: 112899 +// gas irOptimized: 112757 // gas legacy: 126596 // gas legacyOptimized: 113823 diff --git a/test/libsolidity/semanticTests/calldata/calldata_bound_bytes.sol b/test/libsolidity/semanticTests/calldata/calldata_attached_to_bytes.sol similarity index 100% rename from test/libsolidity/semanticTests/calldata/calldata_bound_bytes.sol rename to test/libsolidity/semanticTests/calldata/calldata_attached_to_bytes.sol diff --git a/test/libsolidity/semanticTests/calldata/calldata_bound_dynamic_array_or_slice.sol b/test/libsolidity/semanticTests/calldata/calldata_attached_to_dynamic_array_or_slice.sol similarity index 100% rename from test/libsolidity/semanticTests/calldata/calldata_bound_dynamic_array_or_slice.sol rename to test/libsolidity/semanticTests/calldata/calldata_attached_to_dynamic_array_or_slice.sol diff --git a/test/libsolidity/semanticTests/calldata/calldata_bound_static_array.sol b/test/libsolidity/semanticTests/calldata/calldata_attached_to_static_array.sol similarity index 100% rename from test/libsolidity/semanticTests/calldata/calldata_bound_static_array.sol rename to test/libsolidity/semanticTests/calldata/calldata_attached_to_static_array.sol diff --git a/test/libsolidity/semanticTests/calldata/calldata_bound_struct.sol b/test/libsolidity/semanticTests/calldata/calldata_attached_to_struct.sol similarity index 100% rename from test/libsolidity/semanticTests/calldata/calldata_bound_struct.sol rename to test/libsolidity/semanticTests/calldata/calldata_attached_to_struct.sol diff --git a/test/libsolidity/semanticTests/functionCall/bound_function_in_function.sol b/test/libsolidity/semanticTests/functionCall/call_attached_library_function_on_function.sol similarity index 100% rename from test/libsolidity/semanticTests/functionCall/bound_function_in_function.sol rename to test/libsolidity/semanticTests/functionCall/call_attached_library_function_on_function.sol diff --git a/test/libsolidity/semanticTests/functionCall/bound_function_in_var.sol b/test/libsolidity/semanticTests/functionCall/call_attached_library_function_on_storage_variable.sol similarity index 100% rename from test/libsolidity/semanticTests/functionCall/bound_function_in_var.sol rename to test/libsolidity/semanticTests/functionCall/call_attached_library_function_on_storage_variable.sol diff --git a/test/libsolidity/semanticTests/functionCall/bound_function_to_string.sol b/test/libsolidity/semanticTests/functionCall/call_attached_library_function_on_string.sol similarity index 100% rename from test/libsolidity/semanticTests/functionCall/bound_function_to_string.sol rename to test/libsolidity/semanticTests/functionCall/call_attached_library_function_on_string.sol diff --git a/test/libsolidity/semanticTests/libraries/bound_to_calldata.sol b/test/libsolidity/semanticTests/libraries/attached_internal_library_function_accepting_calldata.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/bound_to_calldata.sol rename to test/libsolidity/semanticTests/libraries/attached_internal_library_function_accepting_calldata.sol diff --git a/test/libsolidity/semanticTests/libraries/bound_returning_calldata.sol b/test/libsolidity/semanticTests/libraries/attached_internal_library_function_returning_calldata.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/bound_returning_calldata.sol rename to test/libsolidity/semanticTests/libraries/attached_internal_library_function_returning_calldata.sol diff --git a/test/libsolidity/semanticTests/libraries/bound_to_calldata_external.sol b/test/libsolidity/semanticTests/libraries/attached_public_library_function_accepting_calldata.sol.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/bound_to_calldata_external.sol rename to test/libsolidity/semanticTests/libraries/attached_public_library_function_accepting_calldata.sol.sol diff --git a/test/libsolidity/semanticTests/libraries/bound_returning_calldata_external.sol b/test/libsolidity/semanticTests/libraries/attached_public_library_function_returning_calldata.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/bound_returning_calldata_external.sol rename to test/libsolidity/semanticTests/libraries/attached_public_library_function_returning_calldata.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_call_bound_with_parentheses.sol b/test/libsolidity/semanticTests/libraries/internal_call_attached_with_parentheses.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_call_bound_with_parentheses.sol rename to test/libsolidity/semanticTests/libraries/internal_call_attached_with_parentheses.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_call_bound_with_parentheses1.sol b/test/libsolidity/semanticTests/libraries/internal_call_unattached_with_parentheses.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_call_bound_with_parentheses1.sol rename to test/libsolidity/semanticTests/libraries/internal_call_unattached_with_parentheses.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_address.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_address.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_address.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_address.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_address_named_send_transfer.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_address_named_send_transfer.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_address_named_send_transfer.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_address_named_send_transfer.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_array_named_pop_push.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_array_named_pop_push.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_array_named_pop_push.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_array_named_pop_push.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_bool.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_bool.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_bool.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_bool.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_contract.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_contract.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_contract.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_contract.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_dynamic_array.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_dynamic_array.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_dynamic_array.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_dynamic_array.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_enum.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_enum.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_enum.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_enum.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_external_function.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_external_function_type.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_external_function.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_external_function_type.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_fixed_array.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_fixed_array.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_fixed_array.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_fixed_array.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_fixed_bytes.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_fixed_bytes.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_fixed_bytes.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_fixed_bytes.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_integer.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_integer.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_integer.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_integer.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_interface.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_interface.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_interface.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_interface.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_internal_function.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_internal_function_type.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_internal_function.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_internal_function_type.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_function_named_selector.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_internal_function_type_named_selector.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_function_named_selector.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_internal_function_type_named_selector.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_literal.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_literal.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_literal.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_literal.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_mapping.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_mapping.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_mapping.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_mapping.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_string.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_string_accepting_memory.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_string.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_string_accepting_memory.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_storage_string.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_string_accepting_storage.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound_to_storage_string.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_string_accepting_storage.sol diff --git a/test/libsolidity/semanticTests/libraries/internal_library_function_bound.sol b/test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_struct.sol similarity index 100% rename from test/libsolidity/semanticTests/libraries/internal_library_function_bound.sol rename to test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_struct.sol diff --git a/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol index cfec3844f..aecde10dc 100644 --- a/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol +++ b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol @@ -53,14 +53,14 @@ contract C { // ---- // from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 123062 +// gas irOptimized: 123041 // gas legacy: 130289 // gas legacyOptimized: 128785 // from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 121776 +// gas irOptimized: 121737 // gas legacy: 123341 // gas legacyOptimized: 121892 // from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -// gas irOptimized: 115169 +// gas irOptimized: 115127 // gas legacy: 122579 // gas legacyOptimized: 120829 diff --git a/test/libsolidity/semanticTests/structs/struct_copy.sol b/test/libsolidity/semanticTests/structs/struct_copy.sol index 27e726f15..e5960ce1e 100644 --- a/test/libsolidity/semanticTests/structs/struct_copy.sol +++ b/test/libsolidity/semanticTests/structs/struct_copy.sol @@ -36,7 +36,7 @@ contract c { // ---- // set(uint256): 7 -> true -// gas irOptimized: 110032 +// gas irOptimized: 109897 // gas legacy: 110616 // gas legacyOptimized: 110006 // retrieve(uint256): 7 -> 1, 3, 4, 2 diff --git a/test/libsolidity/semanticTests/using/using_global_invisible.sol b/test/libsolidity/semanticTests/using/using_global_invisible.sol index 2ad94f050..8db7a9a05 100644 --- a/test/libsolidity/semanticTests/using/using_global_invisible.sol +++ b/test/libsolidity/semanticTests/using/using_global_invisible.sol @@ -29,7 +29,7 @@ import {C} from "B"; contract D { function test() public returns (uint) { C c = new C(); - // This tests that bound functions are available + // This tests that attached functions are available // even if the type is not available by name. // This is a regular function call, a // public and an internal library call diff --git a/test/libsolidity/smtCheckerTests/functions/functions_bound_1.sol b/test/libsolidity/smtCheckerTests/functions/functions_attached_1.sol similarity index 100% rename from test/libsolidity/smtCheckerTests/functions/functions_bound_1.sol rename to test/libsolidity/smtCheckerTests/functions/functions_attached_1.sol diff --git a/test/libsolidity/smtCheckerTests/functions/functions_bound_1_fail.sol b/test/libsolidity/smtCheckerTests/functions/functions_attached_1_fail.sol similarity index 100% rename from test/libsolidity/smtCheckerTests/functions/functions_bound_1_fail.sol rename to test/libsolidity/smtCheckerTests/functions/functions_attached_1_fail.sol diff --git a/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_library_bound_function_returning_struct.sol b/test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_library_attached_function_returning_struct.sol similarity index 100% rename from test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_library_bound_function_returning_struct.sol rename to test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_library_attached_function_returning_struct.sol diff --git a/test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_library_function_pointer_accepting_struct.sol b/test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_library_function_pointer_accepting_struct.sol index 5682ede4d..2d2e75684 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_library_function_pointer_accepting_struct.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_library_function_pointer_accepting_struct.sol @@ -22,4 +22,4 @@ contract Test { } } // ---- -// TypeError 9574: (B:269-313): Type function (struct L.Item memory) is not implicitly convertible to expected type function (struct L.Item memory) external. Special functions can not be converted to function types. +// TypeError 9574: (B:269-313): Type function (struct L.Item memory) is not implicitly convertible to expected type function (struct L.Item memory) external. Special functions cannot be converted to function types. diff --git a/test/libsolidity/syntaxTests/constructor/constructor_function_parameter_disallowed_conversion.sol b/test/libsolidity/syntaxTests/constructor/constructor_function_parameter_disallowed_conversion.sol index c32dc60b5..e22462daa 100644 --- a/test/libsolidity/syntaxTests/constructor/constructor_function_parameter_disallowed_conversion.sol +++ b/test/libsolidity/syntaxTests/constructor/constructor_function_parameter_disallowed_conversion.sol @@ -53,7 +53,7 @@ contract C { // TypeError 9553: (415-428): Invalid type for argument in function call. Invalid implicit conversion from function () view external returns (uint256) to function () pure external returns (uint256) requested. // TypeError 9553: (465-481): Invalid type for argument in function call. Invalid implicit conversion from function () external returns (uint256) to function () pure external returns (uint256) requested. // TypeError 9553: (518-545): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) pure external returns (uint256) to function () pure external returns (uint256) requested. -// TypeError 9553: (582-589): Invalid type for argument in function call. Invalid implicit conversion from function () view returns (uint256) to function () pure external returns (uint256) requested. Special functions can not be converted to function types. -// TypeError 9553: (626-629): Invalid type for argument in function call. Invalid implicit conversion from function () pure returns (uint256) to function () pure external returns (uint256) requested. Special functions can not be converted to function types. -// TypeError 9553: (666-686): Invalid type for argument in function call. Invalid implicit conversion from function () pure returns (uint256) to function () pure external returns (uint256) requested. Special functions can not be converted to function types. +// TypeError 9553: (582-589): Invalid type for argument in function call. Invalid implicit conversion from function () view returns (uint256) to function () pure external returns (uint256) requested. Special functions cannot be converted to function types. +// TypeError 9553: (626-629): Invalid type for argument in function call. Invalid implicit conversion from function () pure returns (uint256) to function () pure external returns (uint256) requested. Special functions cannot be converted to function types. +// TypeError 9553: (666-686): Invalid type for argument in function call. Invalid implicit conversion from function () pure returns (uint256) to function () pure external returns (uint256) requested. Special functions cannot be converted to function types. // TypeError 9582: (723-748): Member "testInternalFunction" not found or not visible after argument-dependent lookup in contract C. diff --git a/test/libsolidity/syntaxTests/errors/error_to_function_conversion.sol b/test/libsolidity/syntaxTests/errors/error_to_function_conversion.sol index e37a6892d..6b2350cd0 100644 --- a/test/libsolidity/syntaxTests/errors/error_to_function_conversion.sol +++ b/test/libsolidity/syntaxTests/errors/error_to_function_conversion.sol @@ -4,4 +4,4 @@ contract C { function() internal pure x = E; } // ---- -// TypeError 7407: (58-59): Type error E() is not implicitly convertible to expected type function () pure. Special functions can not be converted to function types. +// TypeError 7407: (58-59): Type error E() is not implicitly convertible to expected type function () pure. Special functions cannot be converted to function types. diff --git a/test/libsolidity/syntaxTests/events/event_library_function.sol b/test/libsolidity/syntaxTests/events/event_library_function.sol index 382786faa..7a1b793f3 100644 --- a/test/libsolidity/syntaxTests/events/event_library_function.sol +++ b/test/libsolidity/syntaxTests/events/event_library_function.sol @@ -30,6 +30,6 @@ contract E { } } // ---- -// TypeError 9553: (140-143): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested. Special functions can not be converted to function types. -// TypeError 9553: (230-233): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested. Special functions can not be converted to function types. -// TypeError 9553: (345-348): Invalid type for argument in function call. Invalid implicit conversion from function D.f() to function () external requested. Special functions can not be converted to function types. +// TypeError 9553: (140-143): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested. Special functions cannot be converted to function types. +// TypeError 9553: (230-233): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested. Special functions cannot be converted to function types. +// TypeError 9553: (345-348): Invalid type for argument in function call. Invalid implicit conversion from function D.f() to function () external requested. Special functions cannot be converted to function types. diff --git a/test/libsolidity/syntaxTests/events/event_to_function_conversion.sol b/test/libsolidity/syntaxTests/events/event_to_function_conversion.sol index 931e485fc..76d0edc76 100644 --- a/test/libsolidity/syntaxTests/events/event_to_function_conversion.sol +++ b/test/libsolidity/syntaxTests/events/event_to_function_conversion.sol @@ -4,4 +4,4 @@ contract C { function() internal pure x = E; } // ---- -// TypeError 7407: (66-67): Type event E(uint256) is not implicitly convertible to expected type function () pure. Special functions can not be converted to function types. +// TypeError 7407: (66-67): Type event E(uint256) is not implicitly convertible to expected type function () pure. Special functions cannot be converted to function types. diff --git a/test/libsolidity/syntaxTests/functionTypes/assign_bound.sol b/test/libsolidity/syntaxTests/functionTypes/assign_attached_library_function.sol similarity index 77% rename from test/libsolidity/syntaxTests/functionTypes/assign_bound.sol rename to test/libsolidity/syntaxTests/functionTypes/assign_attached_library_function.sol index 37322114d..fd60adce4 100644 --- a/test/libsolidity/syntaxTests/functionTypes/assign_bound.sol +++ b/test/libsolidity/syntaxTests/functionTypes/assign_attached_library_function.sol @@ -12,4 +12,4 @@ contract C { } } // ---- -// TypeError 9574: (209-280): Type function (uint256,uint256) pure returns (uint256) is not implicitly convertible to expected type function (uint256,uint256) pure returns (uint256). Bound functions can not be converted to non-bound functions. +// TypeError 9574: (209-280): Type function (uint256,uint256) pure returns (uint256) is not implicitly convertible to expected type function (uint256,uint256) pure returns (uint256). Attached functions cannot be converted into unattached functions. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/262_bound_function_in_var.sol b/test/libsolidity/syntaxTests/functionTypes/assign_attached_library_function_storage_arg.sol similarity index 87% rename from test/libsolidity/syntaxTests/nameAndTypeResolution/262_bound_function_in_var.sol rename to test/libsolidity/syntaxTests/functionTypes/assign_attached_library_function_storage_arg.sol index 2463bee5e..277880b97 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/262_bound_function_in_var.sol +++ b/test/libsolidity/syntaxTests/functionTypes/assign_attached_library_function_storage_arg.sol @@ -9,5 +9,5 @@ contract C { } } // ---- -// TypeError 9574: (218-271): Type function (struct D.s storage pointer,uint256) returns (uint256) is not implicitly convertible to expected type function (struct D.s storage pointer,uint256) returns (uint256). Bound functions can not be converted to non-bound functions. +// TypeError 9574: (218-271): Type function (struct D.s storage pointer,uint256) returns (uint256) is not implicitly convertible to expected type function (struct D.s storage pointer,uint256) returns (uint256). Attached functions cannot be converted into unattached functions. // TypeError 6160: (298-302): Wrong argument count for function call: 1 arguments given but expected 2. diff --git a/test/libsolidity/syntaxTests/functionTypes/assign_builtin.sol b/test/libsolidity/syntaxTests/functionTypes/assign_builtin.sol index cb795fede..32cc005df 100644 --- a/test/libsolidity/syntaxTests/functionTypes/assign_builtin.sol +++ b/test/libsolidity/syntaxTests/functionTypes/assign_builtin.sol @@ -4,4 +4,4 @@ contract C { } } // ---- -// TypeError 9574: (42-103): Type function (uint256) view returns (bytes32) is not implicitly convertible to expected type function (uint256) view returns (bytes32). Special functions can not be converted to function types. +// TypeError 9574: (42-103): Type function (uint256) view returns (bytes32) is not implicitly convertible to expected type function (uint256) view returns (bytes32). Special functions cannot be converted to function types. diff --git a/test/libsolidity/syntaxTests/functionTypes/external_library_function_to_external_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/external_library_function_to_external_function_type.sol index 0d7030606..c9c87a2cc 100644 --- a/test/libsolidity/syntaxTests/functionTypes/external_library_function_to_external_function_type.sol +++ b/test/libsolidity/syntaxTests/functionTypes/external_library_function_to_external_function_type.sol @@ -10,5 +10,5 @@ contract C { } } // ---- -// TypeError 9553: (230-233): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) returns (uint256) to function (uint256) external returns (uint256) requested. Special functions can not be converted to function types. -// TypeError 9574: (244-305): Type function (uint256) returns (uint256) is not implicitly convertible to expected type function (uint256) external returns (uint256). Special functions can not be converted to function types. +// TypeError 9553: (230-233): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) returns (uint256) to function (uint256) external returns (uint256) requested. Special functions cannot be converted to function types. +// TypeError 9574: (244-305): Type function (uint256) returns (uint256) is not implicitly convertible to expected type function (uint256) external returns (uint256). Special functions cannot be converted to function types. diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol index 08b1b26e3..cd0800c3d 100644 --- a/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol +++ b/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol @@ -3,4 +3,4 @@ contract test { function(bytes memory) external internal a = fa; } // ---- -// TypeError 7407: (106-108): Type function (bytes memory) is not implicitly convertible to expected type function (bytes memory) external. Special functions can not be converted to function types. +// TypeError 7407: (106-108): Type function (bytes memory) is not implicitly convertible to expected type function (bytes memory) external. Special functions cannot be converted to function types. diff --git a/test/libsolidity/syntaxTests/functionTypes/inline_array_with_bound_function.sol b/test/libsolidity/syntaxTests/functionTypes/inline_array_with_attached_function.sol similarity index 100% rename from test/libsolidity/syntaxTests/functionTypes/inline_array_with_bound_function.sol rename to test/libsolidity/syntaxTests/functionTypes/inline_array_with_attached_function.sol diff --git a/test/libsolidity/syntaxTests/functionTypes/inline_array_with_bound_function_mixed.sol b/test/libsolidity/syntaxTests/functionTypes/inline_array_with_attached_function_mixed.sol similarity index 100% rename from test/libsolidity/syntaxTests/functionTypes/inline_array_with_bound_function_mixed.sol rename to test/libsolidity/syntaxTests/functionTypes/inline_array_with_attached_function_mixed.sol diff --git a/test/libsolidity/syntaxTests/functionTypes/ternary_with_bound_functions.sol b/test/libsolidity/syntaxTests/functionTypes/ternary_with_attached_functions.sol similarity index 100% rename from test/libsolidity/syntaxTests/functionTypes/ternary_with_bound_functions.sol rename to test/libsolidity/syntaxTests/functionTypes/ternary_with_attached_functions.sol diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/259_using_for_not_used.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/259_using_for_not_used.sol index abda74579..819ef969b 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/259_using_for_not_used.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/259_using_for_not_used.sol @@ -2,10 +2,10 @@ library D { function double(uint self) public returns (uint) { return 2; } } contract C { using D for uint; function f(uint16 a) public returns (uint) { - // This is an error because the function is only bound to uint. - // Had it been bound to *, it would have worked. + // This is an error because the function is only attached to uint. + // Had it been attached to *, it would have worked. return a.double(); } } // ---- -// TypeError 9582: (305-313): Member "double" not found or not visible after argument-dependent lookup in uint16. +// TypeError 9582: (311-319): Member "double" not found or not visible after argument-dependent lookup in uint16. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/261_using_for_arbitrary_mismatch.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/261_using_for_arbitrary_mismatch.sol index 99aef98a8..f0076a15c 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/261_using_for_arbitrary_mismatch.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/261_using_for_arbitrary_mismatch.sol @@ -2,9 +2,9 @@ library D { function double(bytes32 self) public returns (uint) { return 2; } } contract C { using D for *; function f(uint a) public returns (uint) { - // Bound to a, but self type does not match. + // Attached to a, but self type does not match. return a.double(); } } // ---- -// TypeError 9582: (227-235): Member "double" not found or not visible after argument-dependent lookup in uint256. +// TypeError 9582: (230-238): Member "double" not found or not visible after argument-dependent lookup in uint256. diff --git a/test/libsolidity/syntaxTests/specialFunctions/encodeCall_fail_funType.sol b/test/libsolidity/syntaxTests/specialFunctions/encodeCall_fail_funType.sol index e2de48387..9ac254c99 100644 --- a/test/libsolidity/syntaxTests/specialFunctions/encodeCall_fail_funType.sol +++ b/test/libsolidity/syntaxTests/specialFunctions/encodeCall_fail_funType.sol @@ -43,7 +43,7 @@ contract C is Base { abi.encodeCall(L.fInternal, (1, "123")); abi.encodeCall(L.fExternal, (1, "123")); } - function failBoundLibraryPointerCall() public returns (bytes memory) { + function failAttachedLibraryPointerCall() public returns (bytes memory) { uint256 x = 1; return abi.encodeCall(x.fExternal, (1, "123")); } @@ -70,9 +70,9 @@ contract C is Base { // TypeError 3509: (1187-1207): Expected regular external function type, or external view on public function. Provided internal function. // TypeError 3509: (1286-1297): Expected regular external function type, or external view on public function. Provided internal function. // TypeError 3509: (1329-1340): Expected regular external function type, or external view on public function. Cannot use library functions for abi.encodeCall. -// TypeError 3509: (1471-1482): Expected regular external function type, or external view on public function. Cannot use library functions for abi.encodeCall. -// TypeError 3509: (1592-1601): Expected regular external function type, or external view on public function. Provided internal function. Did you forget to prefix "this."? -// TypeError 3509: (1722-1745): Expected regular external function type, or external view on public function. Provided internal function. Functions from base contracts have to be external. -// TypeError 3509: (1771-1796): Expected regular external function type, or external view on public function. Provided internal function. Functions from base contracts have to be external. -// TypeError 3509: (1902-1911): Expected regular external function type, or external view on public function. Provided internal function. -// TypeError 3509: (2010-2019): Expected regular external function type, or external view on public function. Provided creation function. +// TypeError 3509: (1474-1485): Expected regular external function type, or external view on public function. Cannot use library functions for abi.encodeCall. +// TypeError 3509: (1595-1604): Expected regular external function type, or external view on public function. Provided internal function. Did you forget to prefix "this."? +// TypeError 3509: (1725-1748): Expected regular external function type, or external view on public function. Provided internal function. Functions from base contracts have to be external. +// TypeError 3509: (1774-1799): Expected regular external function type, or external view on public function. Provided internal function. Functions from base contracts have to be external. +// TypeError 3509: (1905-1914): Expected regular external function type, or external view on public function. Provided internal function. +// TypeError 3509: (2013-2022): Expected regular external function type, or external view on public function. Provided creation function. diff --git a/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_base_name_to_var.sol b/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_base_name_to_var.sol index 9b988bb6e..72c09455c 100644 --- a/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_base_name_to_var.sol +++ b/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_base_name_to_var.sol @@ -10,5 +10,5 @@ contract B is A { } } // ---- -// TypeError 9574: (133-160): Type function A.f() is not implicitly convertible to expected type function () external. Special functions can not be converted to function types. -// TypeError 9574: (170-202): Type function A.g() pure is not implicitly convertible to expected type function () pure external. Special functions can not be converted to function types. +// TypeError 9574: (133-160): Type function A.f() is not implicitly convertible to expected type function () external. Special functions cannot be converted to function types. +// TypeError 9574: (170-202): Type function A.g() pure is not implicitly convertible to expected type function () pure external. Special functions cannot be converted to function types. diff --git a/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_contract_name_to_var.sol b/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_contract_name_to_var.sol index 682a7a110..6dcce143d 100644 --- a/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_contract_name_to_var.sol +++ b/test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_contract_name_to_var.sol @@ -10,5 +10,5 @@ contract B { } } // ---- -// TypeError 9574: (128-155): Type function A.f() is not implicitly convertible to expected type function () external. Special functions can not be converted to function types. -// TypeError 9574: (165-197): Type function A.g() pure is not implicitly convertible to expected type function () pure external. Special functions can not be converted to function types. +// TypeError 9574: (128-155): Type function A.f() is not implicitly convertible to expected type function () external. Special functions cannot be converted to function types. +// TypeError 9574: (165-197): Type function A.g() pure is not implicitly convertible to expected type function () pure external. Special functions cannot be converted to function types. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/wrap_unwrap_assign_err.sol b/test/libsolidity/syntaxTests/userDefinedValueType/wrap_unwrap_assign_err.sol index 15bc15fa0..30955f310 100644 --- a/test/libsolidity/syntaxTests/userDefinedValueType/wrap_unwrap_assign_err.sol +++ b/test/libsolidity/syntaxTests/userDefinedValueType/wrap_unwrap_assign_err.sol @@ -4,5 +4,5 @@ function test() pure { function (int) returns (MyInt) g = MyInt.wrap; } // ---- -// TypeError 9574: (46-93): Type function (MyInt) pure returns (int256) is not implicitly convertible to expected type function (MyInt) returns (int256). Special functions can not be converted to function types. -// TypeError 9574: (99-144): Type function (int256) pure returns (MyInt) is not implicitly convertible to expected type function (int256) returns (MyInt). Special functions can not be converted to function types. +// TypeError 9574: (46-93): Type function (MyInt) pure returns (int256) is not implicitly convertible to expected type function (MyInt) returns (int256). Special functions cannot be converted to function types. +// TypeError 9574: (99-144): Type function (int256) pure returns (MyInt) is not implicitly convertible to expected type function (int256) returns (MyInt). Special functions cannot be converted to function types. diff --git a/test/libsolidity/syntaxTests/bound/bound_to_calldata_struct.sol b/test/libsolidity/syntaxTests/using/bound_calldata_parameter_accepting_calldata.sol similarity index 100% rename from test/libsolidity/syntaxTests/bound/bound_to_calldata_struct.sol rename to test/libsolidity/syntaxTests/using/bound_calldata_parameter_accepting_calldata.sol diff --git a/test/libsolidity/syntaxTests/bound/bound_calldata.sol b/test/libsolidity/syntaxTests/using/bound_calldata_parameter_not_accepting_memory.sol similarity index 100% rename from test/libsolidity/syntaxTests/bound/bound_calldata.sol rename to test/libsolidity/syntaxTests/using/bound_calldata_parameter_not_accepting_memory.sol diff --git a/test/libsolidity/syntaxTests/using/free_functions_implicit_conversion_err.sol b/test/libsolidity/syntaxTests/using/free_functions_implicit_conversion_err.sol index a1fe8c7b8..32a49bbb7 100644 --- a/test/libsolidity/syntaxTests/using/free_functions_implicit_conversion_err.sol +++ b/test/libsolidity/syntaxTests/using/free_functions_implicit_conversion_err.sol @@ -10,5 +10,5 @@ contract C { using {id} for S; } // ---- -// TypeError 3100: (112-114): The function "id" cannot be bound to the type "uint256" because the type cannot be implicitly converted to the first argument of the function ("uint16"). -// TypeError 3100: (140-142): The function "id" cannot be bound to the type "struct S" because the type cannot be implicitly converted to the first argument of the function ("uint16"). +// TypeError 3100: (112-114): The function "id" cannot be attached to the type "uint256" because the type cannot be implicitly converted to the first argument of the function ("uint16"). +// TypeError 3100: (140-142): The function "id" cannot be attached to the type "struct S" because the type cannot be implicitly converted to the first argument of the function ("uint16"). diff --git a/test/libsolidity/syntaxTests/using/global_for_asterisk.sol b/test/libsolidity/syntaxTests/using/global_for_asterisk.sol index b5f6d8827..a4ee65a39 100644 --- a/test/libsolidity/syntaxTests/using/global_for_asterisk.sol +++ b/test/libsolidity/syntaxTests/using/global_for_asterisk.sol @@ -2,4 +2,4 @@ using {f} for * global; function f(uint) pure{} // ---- // SyntaxError 8118: (0-23): The type has to be specified explicitly at file level (cannot use '*'). -// SyntaxError 2854: (0-23): Can only globally bind functions to specific types. +// SyntaxError 2854: (0-23): Can only globally attach functions to specific types. diff --git a/test/libsolidity/syntaxTests/using/global_library_with_asterisk.sol b/test/libsolidity/syntaxTests/using/global_library_with_asterisk.sol index 49ac6824d..50860de4a 100644 --- a/test/libsolidity/syntaxTests/using/global_library_with_asterisk.sol +++ b/test/libsolidity/syntaxTests/using/global_library_with_asterisk.sol @@ -2,4 +2,4 @@ using L for * global; library L {} // ---- // SyntaxError 8118: (0-21): The type has to be specified explicitly at file level (cannot use '*'). -// SyntaxError 2854: (0-21): Can only globally bind functions to specific types. +// SyntaxError 2854: (0-21): Can only globally attach functions to specific types. diff --git a/test/libsolidity/syntaxTests/using/global_local_clash.sol b/test/libsolidity/syntaxTests/using/global_local_clash.sol index 1d149417f..5d5d8ae25 100644 --- a/test/libsolidity/syntaxTests/using/global_local_clash.sol +++ b/test/libsolidity/syntaxTests/using/global_local_clash.sol @@ -7,7 +7,7 @@ function f1(S memory _x) pure returns (uint) { return _x.x + 1; } ==== Source: B ==== contract C { // Here, f points to f1, so we end up with two different functions - // bound as S.f + // attached as S.f using {f} for S; function test() pure public @@ -18,4 +18,4 @@ contract C { import {gen as g, f1 as f, S} from "A"; import "A" as A; // ---- -// TypeError 6675: (B:181-186): Member "f" not unique after argument-dependent lookup in struct S memory. +// TypeError 6675: (B:184-189): Member "f" not unique after argument-dependent lookup in struct S memory. diff --git a/test/libsolidity/syntaxTests/using/global_with_asterisk.sol b/test/libsolidity/syntaxTests/using/global_with_asterisk.sol index b5f6d8827..a4ee65a39 100644 --- a/test/libsolidity/syntaxTests/using/global_with_asterisk.sol +++ b/test/libsolidity/syntaxTests/using/global_with_asterisk.sol @@ -2,4 +2,4 @@ using {f} for * global; function f(uint) pure{} // ---- // SyntaxError 8118: (0-23): The type has to be specified explicitly at file level (cannot use '*'). -// SyntaxError 2854: (0-23): Can only globally bind functions to specific types. +// SyntaxError 2854: (0-23): Can only globally attach functions to specific types. diff --git a/test/libsolidity/syntaxTests/bound/interface_using_for.sol b/test/libsolidity/syntaxTests/using/interface_using_for.sol similarity index 100% rename from test/libsolidity/syntaxTests/bound/interface_using_for.sol rename to test/libsolidity/syntaxTests/using/interface_using_for.sol diff --git a/test/libsolidity/syntaxTests/bound/bound_call.sol b/test/libsolidity/syntaxTests/using/library_function_attached_and_called.sol similarity index 100% rename from test/libsolidity/syntaxTests/bound/bound_call.sol rename to test/libsolidity/syntaxTests/using/library_function_attached_and_called.sol diff --git a/test/libsolidity/syntaxTests/bound/bound_no_call.sol b/test/libsolidity/syntaxTests/using/library_function_attached_but_not_called.sol similarity index 100% rename from test/libsolidity/syntaxTests/bound/bound_no_call.sol rename to test/libsolidity/syntaxTests/using/library_function_attached_but_not_called.sol diff --git a/test/libsolidity/syntaxTests/bound/bound_all.sol b/test/libsolidity/syntaxTests/using/library_function_attached_to_all_types.sol similarity index 100% rename from test/libsolidity/syntaxTests/bound/bound_all.sol rename to test/libsolidity/syntaxTests/using/library_function_attached_to_all_types.sol diff --git a/test/libsolidity/syntaxTests/using/using_free_no_parameters_err.sol b/test/libsolidity/syntaxTests/using/using_free_no_parameters_err.sol index e03ba5d10..54fdd825d 100644 --- a/test/libsolidity/syntaxTests/using/using_free_no_parameters_err.sol +++ b/test/libsolidity/syntaxTests/using/using_free_no_parameters_err.sol @@ -4,4 +4,4 @@ function one() pure returns(uint) { using {one} for uint; // ---- -// TypeError 4731: (60-63): The function "one" does not have any parameters, and therefore cannot be bound to the type "uint256". +// TypeError 4731: (60-63): The function "one" does not have any parameters, and therefore cannot be attached to the type "uint256". diff --git a/test/libsolidity/syntaxTests/using/using_free_no_parameters_struct_err.sol b/test/libsolidity/syntaxTests/using/using_free_no_parameters_struct_err.sol index 758993b16..4e15a9d88 100644 --- a/test/libsolidity/syntaxTests/using/using_free_no_parameters_struct_err.sol +++ b/test/libsolidity/syntaxTests/using/using_free_no_parameters_struct_err.sol @@ -2,4 +2,4 @@ struct S { uint8 x; } function f() {} using {f} for S; // ---- -// TypeError 4731: (45-46): The function "f" does not have any parameters, and therefore cannot be bound to the type "struct S". +// TypeError 4731: (45-46): The function "f" does not have any parameters, and therefore cannot be attached to the type "struct S". diff --git a/test/libsolidity/syntaxTests/bound/using_for_library.sol b/test/libsolidity/syntaxTests/using/using_library_for_library.sol similarity index 100% rename from test/libsolidity/syntaxTests/bound/using_for_library.sol rename to test/libsolidity/syntaxTests/using/using_library_for_library.sol diff --git a/test/libsolidity/syntaxTests/using/using_non_free_function_err.sol b/test/libsolidity/syntaxTests/using/using_non_free_function_err.sol index df3b3f65f..fabfcd92c 100644 --- a/test/libsolidity/syntaxTests/using/using_non_free_function_err.sol +++ b/test/libsolidity/syntaxTests/using/using_non_free_function_err.sol @@ -5,5 +5,5 @@ contract C { function g(uint) public { } } // ---- -// TypeError 4167: (24-25): Only file-level functions and library functions can be bound to a type in a "using" statement -// TypeError 4167: (27-28): Only file-level functions and library functions can be bound to a type in a "using" statement +// TypeError 4167: (24-25): Only file-level functions and library functions can be attached to a type in a "using" statement +// TypeError 4167: (27-28): Only file-level functions and library functions can be attached to a type in a "using" statement diff --git a/test/libsolidity/syntaxTests/bound/bound_to_struct.sol b/test/libsolidity/syntaxTests/using/using_struct_for_struct.sol similarity index 100% rename from test/libsolidity/syntaxTests/bound/bound_to_struct.sol rename to test/libsolidity/syntaxTests/using/using_struct_for_struct.sol diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_basic.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_basic.yul new file mode 100644 index 000000000..b838c87e0 --- /dev/null +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_basic.yul @@ -0,0 +1,19 @@ +{ + let x := calldataload(0) + let a := keccak256(0, x) + sstore(a, 2) + let t := mload(2) + let b := keccak256(0, x) + sstore(b, 3) +} +// ---- +// step: loadResolver +// +// { +// { +// let _1 := 0 +// let a := keccak256(_1, calldataload(_1)) +// sstore(a, 2) +// sstore(a, 3) +// } +// } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_expr_mstore.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_expr_mstore.yul new file mode 100644 index 000000000..7b37f8c95 --- /dev/null +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_expr_mstore.yul @@ -0,0 +1,30 @@ +{ + let a := calldataload(0) + sstore(f(keccak256(0, a)), keccak256(0, a)) + sstore(f(keccak256(0, a)), keccak256(0, a)) + sstore(keccak256(0, a), f(keccak256(0, a))) + + function f(x) -> y { + mstore(x, 2) + y := mload(8) + } +} +// ---- +// step: loadResolver +// +// { +// { +// let _1 := 0 +// let a := calldataload(_1) +// let _3 := keccak256(_1, a) +// sstore(f(_3), _3) +// let _8 := keccak256(_1, a) +// sstore(f(_8), _8) +// sstore(keccak256(_1, a), f(keccak256(_1, a))) +// } +// function f(x) -> y +// { +// mstore(x, 2) +// y := mload(8) +// } +// } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_in_expression.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_in_expression.yul new file mode 100644 index 000000000..f4d37d90e --- /dev/null +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_in_expression.yul @@ -0,0 +1,14 @@ +{ + let x := calldataload(0) + sstore(keccak256(0, x), keccak256(0, x)) +} +// ---- +// step: loadResolver +// +// { +// { +// let _1 := 0 +// let _3 := keccak256(_1, calldataload(_1)) +// sstore(_3, _3) +// } +// } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_msize.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_msize.yul new file mode 100644 index 000000000..499a227c2 --- /dev/null +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_msize.yul @@ -0,0 +1,18 @@ +{ + let a := calldataload(0) + let t := msize() + let x := keccak256(0, a) + let y := keccak256(0, a) + sstore(x, y) +} +// ---- +// step: loadResolver +// +// { +// { +// let _1 := 0 +// let a := calldataload(_1) +// let x := keccak256(_1, a) +// sstore(x, keccak256(_1, a)) +// } +// } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_mstore.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_mstore.yul new file mode 100644 index 000000000..65b5931a9 --- /dev/null +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_mstore.yul @@ -0,0 +1,22 @@ +{ + let x := calldataload(0) + let a := keccak256(0x20, x) + sstore(a, 2) + // will disable loading for now, might improve later + mstore(0, 1) + let b := keccak256(0x20, x) + sstore(b, 3) +} +// ---- +// step: loadResolver +// +// { +// { +// let _1 := 0 +// let x := calldataload(_1) +// let _2 := 0x20 +// sstore(keccak256(_2, x), 2) +// mstore(_1, 1) +// sstore(keccak256(_2, x), 3) +// } +// } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_reassigned_branch.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_reassigned_branch.yul new file mode 100644 index 000000000..b780d62b0 --- /dev/null +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_reassigned_branch.yul @@ -0,0 +1,37 @@ +{ + let x := calldataload(0) + let y := calldataload(1) + let a := keccak256(x, y) + if calldataload(2) { + a := 8 + } + let b := keccak256(x, y) + sstore(b, 2) + if calldataload(3) { + x := 8 + } + let c := keccak256(x, y) + sstore(c, 2) + if calldataload(4) { + y := 8 + } + let d := keccak256(x, y) + sstore(d, 2) +} +// ---- +// step: loadResolver +// +// { +// { +// let x := calldataload(0) +// let y := calldataload(1) +// let a := keccak256(x, y) +// let _3 := 2 +// if calldataload(_3) { a := 8 } +// sstore(keccak256(x, y), _3) +// if calldataload(3) { x := 8 } +// sstore(keccak256(x, y), _3) +// if calldataload(4) { y := 8 } +// sstore(keccak256(x, y), _3) +// } +// } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_reassigned_value.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_reassigned_value.yul new file mode 100644 index 000000000..232d76f14 --- /dev/null +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_reuse_reassigned_value.yul @@ -0,0 +1,41 @@ +{ + let x := calldataload(0) + let y := calldataload(1) + let a := keccak256(x, y) + sstore(a, 2) + // reassign value + a := calldataload(10) + let b := keccak256(x, y) + sstore(b, 3) + // reassign arg1 + x := 10 + let c := keccak256(x, y) + sstore(c, 4) + // reassign arg2 + y := 9 + let d := keccak256(x, y) + sstore(d, 5) + // no reassign, check that it is still working here. + let e := keccak256(x, y) + sstore(e, 6) +} +// ---- +// step: loadResolver +// +// { +// { +// let x := calldataload(0) +// let y := calldataload(1) +// let a := keccak256(x, y) +// sstore(a, 2) +// let _4 := 10 +// a := calldataload(_4) +// sstore(keccak256(x, y), 3) +// x := _4 +// sstore(keccak256(_4, y), 4) +// y := 9 +// let d := keccak256(_4, y) +// sstore(d, 5) +// sstore(d, 6) +// } +// }