mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Implement virtual keyword
This commit is contained in:
parent
7d4e4b6088
commit
5b8ff78176
@ -19,16 +19,13 @@ Breaking changes:
|
||||
* Source mappings: Add "modifier depth" as a fifth field in the source mappings.
|
||||
* AST: Inline assembly is exported as structured JSON instead of plain string.
|
||||
|
||||
|
||||
|
||||
* Language Feature: When overriding a function or modifier, the new keyword ``override`` must be used. When overriding a function or modifier defined in multiple parallel bases, all bases must be listed in parentheses after the keyword like so: ``override(Base1, Base2)``
|
||||
|
||||
Language Features:
|
||||
* Allow global enums and structs.
|
||||
* Allow underscores as delimiters in hex strings.
|
||||
* Allow explicit conversions from ``address`` to ``address payable`` via ``payable(...)``.
|
||||
* Introduce syntax for array slices and implement them for dynamic calldata arrays.
|
||||
* Introduce ``push()`` for dynamic storage arrays. It returns a reference to the newly allocated element, if applicable.
|
||||
* Introduce ``virtual`` and ``override`` keywords
|
||||
* Modify ``push(element)`` for dynamic storage arrays such that it does not return the new length anymore.
|
||||
* Yul: Introduce ``leave`` statement that exits the current function.
|
||||
|
||||
|
@ -60,6 +60,8 @@ This section highlights changes that affect syntax and semantics.
|
||||
which send value will revert. If you only implement the receive and not the fallback function, calling a non-existing function on your contract in error is not possible anymore. Unless you are following an upgrade or proxy
|
||||
pattern, you should not need to implement the fallback function.
|
||||
|
||||
* Functions can now only be overridden when they are either marked with the ``virtual`` keyword or defined in an interface. When overriding a function or modifier, the new keyword ``override`` must be used. When overriding a function or modifier defined in multiple parallel bases, all bases must be listed in parentheses after the keyword like so: ``override(Base1, Base2)``.
|
||||
|
||||
|
||||
How to update your code
|
||||
=======================
|
||||
@ -81,6 +83,8 @@ This section gives detailed instructions on how to update prior code for every b
|
||||
|
||||
* Choose unique identifiers for variable declarations in inline assembly that do not conflict with declartions outside the inline assembly block.
|
||||
|
||||
* Add ``virtual`` to every non-interface function you intend to override. For single inheritance, add ``override`` to every overriding function. For multiple inheritance, add ``override(A, B, ..)``, where you list all contracts that define the overridden function in the brackets. When multiple bases define the same function, the inheriting contract must override all conflicting functions.
|
||||
|
||||
New Features
|
||||
============
|
||||
|
||||
|
@ -24,7 +24,7 @@ all defined functions. The usage of an abstract contract as a base class is show
|
||||
pragma solidity >=0.4.0 <0.7.0;
|
||||
|
||||
abstract contract Feline {
|
||||
function utterance() public returns (bytes32);
|
||||
function utterance() public virtual returns (bytes32);
|
||||
}
|
||||
|
||||
contract Cat is Feline {
|
||||
|
@ -42,7 +42,7 @@ Details are given in the following example.
|
||||
// internal functions and state variables. These cannot be
|
||||
// accessed externally via `this`, though.
|
||||
contract Mortal is Owned {
|
||||
function kill() public {
|
||||
function kill() virtual public {
|
||||
if (msg.sender == owner) selfdestruct(owner);
|
||||
}
|
||||
}
|
||||
@ -77,7 +77,7 @@ Details are given in the following example.
|
||||
// types of output parameters, that causes an error.
|
||||
// Both local and message-based function calls take these overrides
|
||||
// into account.
|
||||
function kill() public override {
|
||||
function kill() public virtual override {
|
||||
if (msg.sender == owner) {
|
||||
Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970);
|
||||
NameReg(config.lookup(1)).unregister();
|
||||
@ -115,17 +115,17 @@ seen in the following example::
|
||||
}
|
||||
|
||||
contract mortal is owned {
|
||||
function kill() public {
|
||||
function kill() public virtual {
|
||||
if (msg.sender == owner) selfdestruct(owner);
|
||||
}
|
||||
}
|
||||
|
||||
contract Base1 is mortal {
|
||||
function kill() public override { /* do cleanup 1 */ mortal.kill(); }
|
||||
function kill() public virtual override { /* do cleanup 1 */ mortal.kill(); }
|
||||
}
|
||||
|
||||
contract Base2 is mortal {
|
||||
function kill() public override { /* do cleanup 2 */ mortal.kill(); }
|
||||
function kill() public virtual override { /* do cleanup 2 */ mortal.kill(); }
|
||||
}
|
||||
|
||||
contract Final is Base1, Base2 {
|
||||
@ -144,18 +144,18 @@ explicitly in the final override, but this function will bypass
|
||||
}
|
||||
|
||||
contract mortal is owned {
|
||||
function kill() public {
|
||||
function kill() virtual public {
|
||||
if (msg.sender == owner) selfdestruct(owner);
|
||||
}
|
||||
}
|
||||
|
||||
contract Base1 is mortal {
|
||||
function kill() public override { /* do cleanup 1 */ super.kill(); }
|
||||
function kill() public virtual override { /* do cleanup 1 */ super.kill(); }
|
||||
}
|
||||
|
||||
|
||||
contract Base2 is mortal {
|
||||
function kill() public override { /* do cleanup 2 */ super.kill(); }
|
||||
function kill() public virtual override { /* do cleanup 2 */ super.kill(); }
|
||||
}
|
||||
|
||||
contract Final is Base1, Base2 {
|
||||
@ -190,7 +190,7 @@ function header as shown in this example:
|
||||
|
||||
contract Base
|
||||
{
|
||||
function foo() public {}
|
||||
function foo() virtual public {}
|
||||
}
|
||||
|
||||
contract Middle is Base {}
|
||||
@ -212,12 +212,12 @@ bases, it has to explicitly override it:
|
||||
|
||||
contract Base1
|
||||
{
|
||||
function foo() public {}
|
||||
function foo() virtual public {}
|
||||
}
|
||||
|
||||
contract Base2
|
||||
{
|
||||
function foo() public {}
|
||||
function foo() virtual public {}
|
||||
}
|
||||
|
||||
contract Inherited is Base1, Base2
|
||||
|
@ -92,8 +92,8 @@ Yes::
|
||||
pragma solidity >=0.4.0 <0.7.0;
|
||||
|
||||
abstract contract A {
|
||||
function spam() public pure;
|
||||
function ham() public pure;
|
||||
function spam() public virtual pure;
|
||||
function ham() public virtual pure;
|
||||
}
|
||||
|
||||
|
||||
|
@ -245,15 +245,14 @@ void ContractLevelChecker::checkIllegalOverrides(ContractDefinition const& _cont
|
||||
|
||||
for (FunctionDefinition const* function: _contract.definedFunctions())
|
||||
{
|
||||
if (function->isConstructor())
|
||||
continue;
|
||||
|
||||
if (contains_if(modSet, MatchByName{function->name()}))
|
||||
m_errorReporter.typeError(function->location(), "Override changes modifier to function.");
|
||||
|
||||
// Skip if not overridable
|
||||
if (!function->isOverridable())
|
||||
continue;
|
||||
|
||||
// No inheriting functions found
|
||||
if (funcSet.find(function) == funcSet.cend() && function->overrides())
|
||||
if (!funcSet.count(function) && function->overrides())
|
||||
m_errorReporter.typeError(
|
||||
function->overrides()->location(),
|
||||
"Function has override specified but does not override anything."
|
||||
@ -279,6 +278,12 @@ bool ContractLevelChecker::checkFunctionOverride(FunctionDefinition const& _func
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (!_super.virtualSemantics())
|
||||
{
|
||||
overrideError( _super, _function, "Trying to override non-virtual function. Did you forget to add \"virtual\"?", "Overriding function is here:");
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (!functionType->hasEqualReturnTypes(*superType))
|
||||
{
|
||||
overrideError(_function, _super, "Overriding function return types differ.");
|
||||
@ -343,11 +348,11 @@ void ContractLevelChecker::overrideListError(FunctionDefinition const& function,
|
||||
);
|
||||
}
|
||||
|
||||
void ContractLevelChecker::overrideError(CallableDeclaration const& function, CallableDeclaration const& super, string message)
|
||||
void ContractLevelChecker::overrideError(CallableDeclaration const& function, CallableDeclaration const& super, string message, string secondaryMsg)
|
||||
{
|
||||
m_errorReporter.typeError(
|
||||
function.location(),
|
||||
SecondarySourceLocation().append("Overridden function is here:", super.location()),
|
||||
SecondarySourceLocation().append(secondaryMsg, super.location()),
|
||||
message
|
||||
);
|
||||
}
|
||||
@ -653,10 +658,10 @@ void ContractLevelChecker::checkAmbiguousOverrides(ContractDefinition const& _co
|
||||
continue;
|
||||
|
||||
// Not an overridable function
|
||||
if (!(*it)->isOverridable())
|
||||
if ((*it)->isConstructor())
|
||||
{
|
||||
for (begin++; begin != end; begin++)
|
||||
solAssert(!(*begin)->isOverridable(), "All functions in range expected to be non-overridable!");
|
||||
solAssert((*begin)->isConstructor(), "All functions in range expected to be constructors!");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -785,8 +790,7 @@ void ContractLevelChecker::checkOverrideList(FunctionMultiSet const& _funcSet, F
|
||||
for (auto [begin, end] = _funcSet.equal_range(&_function); begin != end; begin++)
|
||||
{
|
||||
// Validate the override
|
||||
if (!checkFunctionOverride(_function, **begin))
|
||||
break;
|
||||
checkFunctionOverride(_function, **begin);
|
||||
|
||||
expectedContracts.insert((*begin)->annotation().contract);
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ private:
|
||||
/// Also stores the direct super function in the AST annotations.
|
||||
bool checkFunctionOverride(FunctionDefinition const& _function, FunctionDefinition const& _super);
|
||||
void overrideListError(FunctionDefinition const& function, std::set<ContractDefinition const*, LessFunction> _secondary, std::string const& _message1, std::string const& _message2);
|
||||
void overrideError(CallableDeclaration const& function, CallableDeclaration const& super, std::string message);
|
||||
void overrideError(CallableDeclaration const& function, CallableDeclaration const& super, std::string message, std::string secondaryMsg = "Overridden function is here:");
|
||||
void checkAbstractFunctions(ContractDefinition const& _contract);
|
||||
/// Checks that the base constructor arguments are properly provided.
|
||||
/// Fills the list of unimplemented functions in _contract's annotations.
|
||||
|
@ -327,6 +327,9 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
|
||||
{
|
||||
bool isLibraryFunction = _function.inContractKind() == ContractDefinition::ContractKind::Library;
|
||||
|
||||
if (_function.markedVirtual() && _function.annotation().contract->isInterface())
|
||||
m_errorReporter.warning(_function.location(), "Interface functions are implicitly \"virtual\"");
|
||||
|
||||
if (_function.isPayable())
|
||||
{
|
||||
if (isLibraryFunction)
|
||||
|
@ -621,12 +621,14 @@ public:
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& returnParameters() const { return m_returnParameters->parameters(); }
|
||||
ParameterList const& parameterList() const { return *m_parameters; }
|
||||
ASTPointer<ParameterList> const& returnParameterList() const { return m_returnParameters; }
|
||||
bool markedVirtual() const { return m_isVirtual; }
|
||||
virtual bool virtualSemantics() const { return markedVirtual(); }
|
||||
|
||||
protected:
|
||||
ASTPointer<ParameterList> m_parameters;
|
||||
ASTPointer<OverrideSpecifier> m_overrides;
|
||||
ASTPointer<ParameterList> m_returnParameters;
|
||||
bool m_isVirtual;
|
||||
bool m_isVirtual = false;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -692,7 +694,6 @@ public:
|
||||
bool isFallback() const { return m_kind == Token::Fallback; }
|
||||
bool isReceive() const { return m_kind == Token::Receive; }
|
||||
Token kind() const { return m_kind; }
|
||||
bool isOverridable() const { return !isConstructor(); }
|
||||
bool isPayable() const { return m_stateMutability == StateMutability::Payable; }
|
||||
std::vector<ASTPointer<ModifierInvocation>> const& modifiers() const { return m_functionModifiers; }
|
||||
Block const& body() const { solAssert(m_body, ""); return *m_body; }
|
||||
@ -717,6 +718,12 @@ public:
|
||||
|
||||
FunctionDefinitionAnnotation& annotation() const override;
|
||||
|
||||
bool virtualSemantics() const override
|
||||
{
|
||||
return
|
||||
CallableDeclaration::virtualSemantics() ||
|
||||
annotation().contract->isInterface();
|
||||
}
|
||||
private:
|
||||
StateMutability m_stateMutability;
|
||||
Token const m_kind;
|
||||
@ -742,7 +749,6 @@ public:
|
||||
bool _isStateVar = false,
|
||||
bool _isIndexed = false,
|
||||
bool _isConstant = false,
|
||||
bool _isVirtual = false,
|
||||
ASTPointer<OverrideSpecifier> const& _overrides = nullptr,
|
||||
Location _referenceLocation = Location::Unspecified
|
||||
):
|
||||
@ -752,7 +758,6 @@ public:
|
||||
m_isStateVariable(_isStateVar),
|
||||
m_isIndexed(_isIndexed),
|
||||
m_isConstant(_isConstant),
|
||||
m_isVirtual(_isVirtual),
|
||||
m_overrides(_overrides),
|
||||
m_location(_referenceLocation) {}
|
||||
|
||||
@ -798,7 +803,6 @@ public:
|
||||
bool isIndexed() const { return m_isIndexed; }
|
||||
bool isConstant() const { return m_isConstant; }
|
||||
ASTPointer<OverrideSpecifier> const& overrides() const { return m_overrides; }
|
||||
bool isVirtual() const { return m_isVirtual; }
|
||||
Location referenceLocation() const { return m_location; }
|
||||
/// @returns a set of allowed storage locations for the variable.
|
||||
std::set<Location> allowedDataLocations() const;
|
||||
@ -819,12 +823,11 @@ private:
|
||||
/// Initially assigned value, can be missing. For local variables, this is stored inside
|
||||
/// VariableDeclarationStatement and not here.
|
||||
ASTPointer<Expression> m_value;
|
||||
bool m_isStateVariable; ///< Whether or not this is a contract state variable
|
||||
bool m_isIndexed; ///< Whether this is an indexed variable (used by events).
|
||||
bool m_isConstant; ///< Whether the variable is a compile-time constant.
|
||||
bool m_isVirtual; ///< Whether the variable is virtual and can be overridden
|
||||
bool m_isStateVariable = false; ///< Whether or not this is a contract state variable
|
||||
bool m_isIndexed = false; ///< Whether this is an indexed variable (used by events).
|
||||
bool m_isConstant = false; ///< Whether the variable is a compile-time constant.
|
||||
ASTPointer<OverrideSpecifier> m_overrides; ///< Contains the override specifier node
|
||||
Location m_location; ///< Location of the variable if it is of reference type.
|
||||
Location m_location = Location::Unspecified; ///< Location of the variable if it is of reference type.
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -466,9 +466,6 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _isStateVari
|
||||
RecursionGuard recursionGuard(*this);
|
||||
FunctionHeaderParserResult result;
|
||||
|
||||
result.isVirtual = false;
|
||||
result.overrides = nullptr;
|
||||
|
||||
VarDeclParserOptions options;
|
||||
options.allowLocationSpecifier = true;
|
||||
result.parameters = parseParameterList(options);
|
||||
@ -689,7 +686,6 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
||||
|
||||
bool isIndexed = false;
|
||||
bool isDeclaredConst = false;
|
||||
bool isVirtual = false;
|
||||
ASTPointer<OverrideSpecifier> overrides = nullptr;
|
||||
Declaration::Visibility visibility(Declaration::Visibility::Default);
|
||||
VariableDeclaration::Location location = VariableDeclaration::Location::Unspecified;
|
||||
@ -720,14 +716,6 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
||||
|
||||
overrides = parseOverrideSpecifier();
|
||||
}
|
||||
else if (_options.isStateVariable && token == Token::Virtual)
|
||||
{
|
||||
if (isVirtual)
|
||||
parserError("Virtual already specified.");
|
||||
|
||||
isVirtual = true;
|
||||
m_scanner->next();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_options.allowIndexed && token == Token::Indexed)
|
||||
@ -793,7 +781,6 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
||||
_options.isStateVariable,
|
||||
isIndexed,
|
||||
isDeclaredConst,
|
||||
isVirtual,
|
||||
overrides,
|
||||
location
|
||||
);
|
||||
@ -826,7 +813,7 @@ ASTPointer<ModifierDefinition> Parser::parseModifierDefinition()
|
||||
ASTPointer<OverrideSpecifier> overrides;
|
||||
bool isVirtual = false;
|
||||
|
||||
while(true)
|
||||
while (true)
|
||||
{
|
||||
if (m_scanner->currentToken() == Token::Override)
|
||||
{
|
||||
|
@ -70,7 +70,7 @@ private:
|
||||
/// This struct is shared for parsing a function header and a function type.
|
||||
struct FunctionHeaderParserResult
|
||||
{
|
||||
bool isVirtual;
|
||||
bool isVirtual = false;
|
||||
ASTPointer<OverrideSpecifier> overrides;
|
||||
ASTPointer<ParameterList> parameters;
|
||||
ASTPointer<ParameterList> returnParameters;
|
||||
|
@ -221,6 +221,7 @@ contract MultiSigWallet {
|
||||
/// @dev Allows anyone to execute a confirmed transaction.
|
||||
/// @param transactionId Transaction ID.
|
||||
function executeTransaction(uint transactionId)
|
||||
virtual
|
||||
public
|
||||
notExecuted(transactionId)
|
||||
{
|
||||
|
@ -51,7 +51,7 @@ contract module {
|
||||
moduleHandlerAddress = newModuleHandlerAddress;
|
||||
}
|
||||
|
||||
function connectModule() external onlyForModuleHandler returns (bool success) {
|
||||
function connectModule() virtual external onlyForModuleHandler returns (bool success) {
|
||||
_connectModule();
|
||||
return true;
|
||||
}
|
||||
@ -77,7 +77,7 @@ contract module {
|
||||
moduleStatus = status.Disconnected;
|
||||
}
|
||||
|
||||
function replaceModule(address payable newModuleAddress) external onlyForModuleHandler returns (bool success) {
|
||||
function replaceModule(address payable newModuleAddress) virtual external onlyForModuleHandler returns (bool success) {
|
||||
_replaceModule(newModuleAddress);
|
||||
return true;
|
||||
}
|
||||
@ -101,10 +101,11 @@ contract module {
|
||||
moduleStatus = status.Disconnected;
|
||||
}
|
||||
|
||||
function transferEvent(address payable from, address payable to, uint256 value) external onlyForModuleHandler returns (bool success) {
|
||||
function transferEvent(address payable from, address payable to, uint256
|
||||
value) virtual external onlyForModuleHandler returns (bool success) {
|
||||
return true;
|
||||
}
|
||||
function newSchellingRoundEvent(uint256 roundID, uint256 reward) external onlyForModuleHandler returns (bool success) {
|
||||
function newSchellingRoundEvent(uint256 roundID, uint256 reward) virtual external onlyForModuleHandler returns (bool success) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -120,9 +120,9 @@ abstract contract Event {
|
||||
|
||||
/// @dev Calculates and returns event hash
|
||||
/// @return Event hash
|
||||
function getEventHash() public view returns (bytes32);
|
||||
function getEventHash() virtual public view returns (bytes32);
|
||||
|
||||
/// @dev Exchanges sender's winning outcome tokens for collateral tokens
|
||||
/// @return Sender's winnings
|
||||
function redeemWinnings() public returns (uint);
|
||||
function redeemWinnings() virtual public returns (uint);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ abstract contract MarketMaker {
|
||||
/*
|
||||
* Public functions
|
||||
*/
|
||||
function calcCost(Market market, uint8 outcomeTokenIndex, uint outcomeTokenCount) public view returns (uint);
|
||||
function calcProfit(Market market, uint8 outcomeTokenIndex, uint outcomeTokenCount) public view returns (uint);
|
||||
function calcMarginalPrice(Market market, uint8 outcomeTokenIndex) public view returns (uint);
|
||||
function calcCost(Market market, uint8 outcomeTokenIndex, uint outcomeTokenCount) virtual public view returns (uint);
|
||||
function calcProfit(Market market, uint8 outcomeTokenIndex, uint outcomeTokenCount) virtual public view returns (uint);
|
||||
function calcMarginalPrice(Market market, uint8 outcomeTokenIndex) virtual public view returns (uint);
|
||||
}
|
||||
|
@ -37,11 +37,11 @@ abstract contract Market {
|
||||
/*
|
||||
* Public functions
|
||||
*/
|
||||
function fund(uint _funding) public;
|
||||
function close() public;
|
||||
function withdrawFees() public returns (uint);
|
||||
function buy(uint8 outcomeTokenIndex, uint outcomeTokenCount, uint maxCost) public returns (uint);
|
||||
function sell(uint8 outcomeTokenIndex, uint outcomeTokenCount, uint minProfit) public returns (uint);
|
||||
function shortSell(uint8 outcomeTokenIndex, uint outcomeTokenCount, uint minProfit) public returns (uint);
|
||||
function calcMarketFee(uint outcomeTokenCost) public view returns (uint);
|
||||
function fund(uint _funding) virtual public;
|
||||
function close() virtual public;
|
||||
function withdrawFees() virtual public returns (uint);
|
||||
function buy(uint8 outcomeTokenIndex, uint outcomeTokenCount, uint maxCost) virtual public returns (uint);
|
||||
function sell(uint8 outcomeTokenIndex, uint outcomeTokenCount, uint minProfit) virtual public returns (uint);
|
||||
function shortSell(uint8 outcomeTokenIndex, uint outcomeTokenCount, uint minProfit) virtual public returns (uint);
|
||||
function calcMarketFee(uint outcomeTokenCost) virtual public view returns (uint);
|
||||
}
|
||||
|
@ -15,5 +15,6 @@ abstract contract MarketFactory {
|
||||
/*
|
||||
* Public functions
|
||||
*/
|
||||
function createMarket(Event eventContract, MarketMaker marketMaker, uint24 fee) public returns (Market);
|
||||
function createMarket(Event eventContract, MarketMaker marketMaker, uint24
|
||||
fee) virtual public returns (Market);
|
||||
}
|
||||
|
@ -4,6 +4,6 @@ pragma solidity >=0.0;
|
||||
/// @title Abstract oracle contract - Functions to be implemented by oracles
|
||||
abstract contract Oracle {
|
||||
|
||||
function isOutcomeSet() public view returns (bool);
|
||||
function getOutcome() public view returns (int);
|
||||
function isOutcomeSet() virtual public view returns (bool);
|
||||
function getOutcome() virtual public view returns (int);
|
||||
}
|
||||
|
@ -14,10 +14,10 @@ abstract contract Token {
|
||||
/*
|
||||
* Public functions
|
||||
*/
|
||||
function transfer(address to, uint value) public returns (bool);
|
||||
function transferFrom(address from, address to, uint value) public returns (bool);
|
||||
function approve(address spender, uint value) public returns (bool);
|
||||
function balanceOf(address owner) public view returns (uint);
|
||||
function allowance(address owner, address spender) public view returns (uint);
|
||||
function totalSupply() public view returns (uint);
|
||||
function transfer(address to, uint value) virtual public returns (bool);
|
||||
function transferFrom(address from, address to, uint value) virtual public returns (bool);
|
||||
function approve(address spender, uint value) virtual public returns (bool);
|
||||
function balanceOf(address owner) virtual public view returns (uint);
|
||||
function allowance(address owner, address spender) virtual public view returns (uint);
|
||||
function totalSupply() virtual public view returns (uint);
|
||||
}
|
||||
|
@ -177,6 +177,7 @@ library Math {
|
||||
/// @param nums Numbers to look through
|
||||
/// @return max Maximum number
|
||||
function max(int[] memory nums)
|
||||
virtual
|
||||
public
|
||||
pure
|
||||
returns (int max)
|
||||
|
@ -46,20 +46,20 @@ static char const* registrarCode = R"DELIMITER(
|
||||
pragma solidity >=0.4.0 <0.7.0;
|
||||
|
||||
abstract contract NameRegister {
|
||||
function addr(string memory _name) public view returns (address o_owner);
|
||||
function name(address _owner) public view returns (string memory o_name);
|
||||
function addr(string memory _name) public virtual view returns (address o_owner);
|
||||
function name(address _owner) public view virtual returns (string memory o_name);
|
||||
}
|
||||
|
||||
abstract contract Registrar is NameRegister {
|
||||
event Changed(string indexed name);
|
||||
event PrimaryChanged(string indexed name, address indexed addr);
|
||||
|
||||
function owner(string memory _name) public view returns (address o_owner);
|
||||
function addr(string memory _name) public override view returns (address o_address);
|
||||
function subRegistrar(string memory _name) public view returns (address o_subRegistrar);
|
||||
function content(string memory _name) public view returns (bytes32 o_content);
|
||||
function owner(string memory _name) public view virtual returns (address o_owner);
|
||||
function addr(string memory _name) public virtual override view returns (address o_address);
|
||||
function subRegistrar(string memory _name) public virtual view returns (address o_subRegistrar);
|
||||
function content(string memory _name) public virtual view returns (bytes32 o_content);
|
||||
|
||||
function name(address _owner) public override view returns (string memory o_name);
|
||||
function name(address _owner) public virtual override view returns (string memory o_name);
|
||||
}
|
||||
|
||||
abstract contract AuctionSystem {
|
||||
@ -67,7 +67,7 @@ abstract contract AuctionSystem {
|
||||
event NewBid(string indexed _name, address _bidder, uint _value);
|
||||
|
||||
/// Function that is called once an auction ends.
|
||||
function onAuctionEnd(string memory _name) internal;
|
||||
function onAuctionEnd(string memory _name) internal virtual;
|
||||
|
||||
function bid(string memory _name, address payable _bidder, uint _value) internal {
|
||||
Auction storage auction = m_auctions[_name];
|
||||
|
@ -58,10 +58,10 @@ pragma solidity >=0.4.0 <0.7.0;
|
||||
abstract contract Registrar {
|
||||
event Changed(string indexed name);
|
||||
|
||||
function owner(string memory _name) public view returns (address o_owner);
|
||||
function addr(string memory _name) public view returns (address o_address);
|
||||
function subRegistrar(string memory _name) public view returns (address o_subRegistrar);
|
||||
function content(string memory _name) public view returns (bytes32 o_content);
|
||||
function owner(string memory _name) public virtual view returns (address o_owner);
|
||||
function addr(string memory _name) public virtual view returns (address o_address);
|
||||
function subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar);
|
||||
function content(string memory _name) public virtual view returns (bytes32 o_content);
|
||||
}
|
||||
|
||||
contract FixedFeeRegistrar is Registrar {
|
||||
|
@ -128,7 +128,7 @@ contract multiowned {
|
||||
}
|
||||
|
||||
// Replaces an owner `_from` with another `_to`.
|
||||
function changeOwner(address _from, address _to) onlymanyowners(keccak256(msg.data)) public {
|
||||
function changeOwner(address _from, address _to) onlymanyowners(keccak256(msg.data)) public virtual {
|
||||
if (isOwner(_to)) return;
|
||||
uint ownerIndex = m_ownerIndex[uint(_from)];
|
||||
if (ownerIndex == 0) return;
|
||||
@ -248,7 +248,7 @@ contract multiowned {
|
||||
}
|
||||
}
|
||||
|
||||
function clearPending() internal {
|
||||
function clearPending() internal virtual {
|
||||
uint length = m_pendingIndex.length;
|
||||
for (uint i = 0; i < length; ++i)
|
||||
if (m_pendingIndex[i] != 0)
|
||||
@ -347,9 +347,9 @@ abstract contract multisig {
|
||||
// FUNCTIONS
|
||||
|
||||
// TODO: document
|
||||
function changeOwner(address _from, address _to) public;
|
||||
function execute(address _to, uint _value, bytes calldata _data) external returns (bytes32);
|
||||
function confirm(bytes32 _h) public returns (bool);
|
||||
function changeOwner(address _from, address _to) public virtual;
|
||||
function execute(address _to, uint _value, bytes calldata _data) external virtual returns (bytes32);
|
||||
function confirm(bytes32 _h) public virtual returns (bool);
|
||||
}
|
||||
|
||||
// usage:
|
||||
|
@ -174,14 +174,14 @@ abstract contract DAOInterface {
|
||||
// );
|
||||
|
||||
/// @notice Create Token with `msg.sender` as the beneficiary
|
||||
receive() external payable;
|
||||
receive() virtual external payable;
|
||||
|
||||
|
||||
/// @dev This function is used to send ether back
|
||||
/// to the DAO, it can also be used to receive payments that should not be
|
||||
/// counted as rewards (donations, grants, etc.)
|
||||
/// @return Whether the DAO received the ether successfully
|
||||
function receiveEther() public returns (bool);
|
||||
function receiveEther() public virtual returns (bool);
|
||||
|
||||
/// @notice `msg.sender` creates a proposal to send `_amount` Wei to
|
||||
/// `_recipient` with the transaction data `_transactionData`. If
|
||||
@ -203,7 +203,7 @@ abstract contract DAOInterface {
|
||||
bytes memory _transactionData,
|
||||
uint _debatingPeriod,
|
||||
bool _newCurator
|
||||
) public payable returns (uint _proposalID);
|
||||
) public virtual payable returns (uint _proposalID);
|
||||
|
||||
/// @notice Check that the proposal with the ID `_proposalID` matches the
|
||||
/// transaction which sends `_amount` with data `_transactionData`
|
||||
@ -218,7 +218,7 @@ abstract contract DAOInterface {
|
||||
address payable _recipient,
|
||||
uint _amount,
|
||||
bytes memory _transactionData
|
||||
) public view returns (bool _codeChecksOut);
|
||||
) public virtual view returns (bool _codeChecksOut);
|
||||
|
||||
/// @notice Vote on proposal `_proposalID` with `_supportsProposal`
|
||||
/// @param _proposalID The proposal ID
|
||||
@ -227,7 +227,7 @@ abstract contract DAOInterface {
|
||||
function vote(
|
||||
uint _proposalID,
|
||||
bool _supportsProposal
|
||||
) public returns (uint _voteID);
|
||||
) public virtual returns (uint _voteID);
|
||||
|
||||
/// @notice Checks whether proposal `_proposalID` with transaction data
|
||||
/// `_transactionData` has been voted for or rejected, and executes the
|
||||
@ -238,7 +238,7 @@ abstract contract DAOInterface {
|
||||
function executeProposal(
|
||||
uint _proposalID,
|
||||
bytes memory _transactionData
|
||||
) public returns (bool _success);
|
||||
) public virtual returns (bool _success);
|
||||
|
||||
/// @notice ATTENTION! I confirm to move my remaining ether to a new DAO
|
||||
/// with `_newCurator` as the new Curator, as has been
|
||||
@ -254,13 +254,13 @@ abstract contract DAOInterface {
|
||||
function splitDAO(
|
||||
uint _proposalID,
|
||||
address payable _newCurator
|
||||
) public returns (bool _success);
|
||||
) public virtual returns (bool _success);
|
||||
|
||||
/// @dev can only be called by the DAO itself through a proposal
|
||||
/// updates the contract of the DAO by sending all ether and rewardTokens
|
||||
/// to the new DAO. The new DAO needs to be approved by the Curator
|
||||
/// @param _newContract the address of the new contract
|
||||
function newContract(address payable _newContract) public;
|
||||
function newContract(address payable _newContract) virtual public;
|
||||
|
||||
|
||||
/// @notice Add a new possible recipient `_recipient` to the whitelist so
|
||||
@ -268,36 +268,36 @@ abstract contract DAOInterface {
|
||||
/// @param _recipient New recipient address
|
||||
/// @dev Can only be called by the current Curator
|
||||
/// @return Whether successful or not
|
||||
function changeAllowedRecipients(address _recipient, bool _allowed) external returns (bool _success);
|
||||
function changeAllowedRecipients(address _recipient, bool _allowed) virtual external returns (bool _success);
|
||||
|
||||
|
||||
/// @notice Change the minimum deposit required to submit a proposal
|
||||
/// @param _proposalDeposit The new proposal deposit
|
||||
/// @dev Can only be called by this DAO (through proposals with the
|
||||
/// recipient being this DAO itself)
|
||||
function changeProposalDeposit(uint _proposalDeposit) external;
|
||||
function changeProposalDeposit(uint _proposalDeposit) virtual external;
|
||||
|
||||
/// @notice Move rewards from the DAORewards managed account
|
||||
/// @param _toMembers If true rewards are moved to the actual reward account
|
||||
/// for the DAO. If not then it's moved to the DAO itself
|
||||
/// @return Whether the call was successful
|
||||
function retrieveDAOReward(bool _toMembers) external returns (bool _success);
|
||||
function retrieveDAOReward(bool _toMembers) virtual external returns (bool _success);
|
||||
|
||||
/// @notice Get my portion of the reward that was sent to `rewardAccount`
|
||||
/// @return Whether the call was successful
|
||||
function getMyReward() public returns (bool _success);
|
||||
function getMyReward() public virtual returns (bool _success);
|
||||
|
||||
/// @notice Withdraw `_account`'s portion of the reward from `rewardAccount`
|
||||
/// to `_account`'s balance
|
||||
/// @return Whether the call was successful
|
||||
function withdrawRewardFor(address payable _account) internal returns (bool _success);
|
||||
function withdrawRewardFor(address payable _account) internal virtual returns (bool _success);
|
||||
|
||||
/// @notice Send `_amount` tokens to `_to` from `msg.sender`. Prior to this
|
||||
/// getMyReward() is called.
|
||||
/// @param _to The address of the recipient
|
||||
/// @param _amount The amount of tokens to be transferred
|
||||
/// @return Whether the transfer was successful or not
|
||||
function transferWithoutReward(address _to, uint256 _amount) public returns (bool success);
|
||||
function transferWithoutReward(address _to, uint256 _amount) public virtual returns (bool success);
|
||||
|
||||
/// @notice Send `_amount` tokens to `_to` from `_from` on the condition it
|
||||
/// is approved by `_from`. Prior to this getMyReward() is called.
|
||||
@ -309,28 +309,28 @@ abstract contract DAOInterface {
|
||||
address payable _from,
|
||||
address _to,
|
||||
uint256 _amount
|
||||
) public returns (bool success);
|
||||
) public virtual returns (bool success);
|
||||
|
||||
/// @notice Doubles the 'minQuorumDivisor' in the case quorum has not been
|
||||
/// achieved in 52 weeks
|
||||
/// @return Whether the change was successful or not
|
||||
function halveMinQuorum() public returns (bool _success);
|
||||
function halveMinQuorum() public virtual returns (bool _success);
|
||||
|
||||
/// @return total number of proposals ever created
|
||||
function numberOfProposals() public view returns (uint _numberOfProposals);
|
||||
function numberOfProposals() public virtual view returns (uint _numberOfProposals);
|
||||
|
||||
/// @param _proposalID Id of the new curator proposal
|
||||
/// @return Address of the new DAO
|
||||
function getNewDAOAddress(uint _proposalID) public view returns (address _newDAO);
|
||||
function getNewDAOAddress(uint _proposalID) public virtual view returns (address _newDAO);
|
||||
|
||||
/// @param _account The address of the account which is checked.
|
||||
/// @return Whether the account is blocked (not allowed to transfer tokens) or not.
|
||||
function isBlocked(address _account) internal returns (bool);
|
||||
function isBlocked(address _account) internal virtual returns (bool);
|
||||
|
||||
/// @notice If the caller is blocked by a proposal whose voting deadline
|
||||
/// has exprired then unblock him.
|
||||
/// @return Whether the account is blocked (not allowed to transfer tokens) or not.
|
||||
function unblockMe() public returns (bool);
|
||||
function unblockMe() public virtual returns (bool);
|
||||
|
||||
event ProposalAdded(
|
||||
uint indexed proposalID,
|
||||
|
@ -33,7 +33,7 @@ abstract contract ManagedAccountInterface {
|
||||
/// @param _amount The amount of wei to send to `_recipient`
|
||||
/// @param _recipient The address to receive `_amount` of wei
|
||||
/// @return True if the send completed
|
||||
function payOut(address payable _recipient, uint _amount) public returns (bool);
|
||||
function payOut(address payable _recipient, uint _amount) public virtual returns (bool);
|
||||
|
||||
event PayOut(address indexed _recipient, uint _amount);
|
||||
}
|
||||
|
@ -45,13 +45,13 @@ abstract contract TokenInterface {
|
||||
|
||||
/// @param _owner The address from which the balance will be retrieved
|
||||
/// @return balance The balance
|
||||
function balanceOf(address _owner) public view returns (uint256 balance);
|
||||
function balanceOf(address _owner) public virtual view returns (uint256 balance);
|
||||
|
||||
/// @notice Send `_amount` tokens to `_to` from `msg.sender`
|
||||
/// @param _to The address of the recipient
|
||||
/// @param _amount The amount of tokens to be transferred
|
||||
/// @return success Whether the transfer was successful or not
|
||||
function transfer(address _to, uint256 _amount) public returns (bool success);
|
||||
function transfer(address _to, uint256 _amount) public virtual returns (bool success);
|
||||
|
||||
/// @notice Send `_amount` tokens to `_to` from `_from` on the condition it
|
||||
/// is approved by `_from`
|
||||
@ -59,14 +59,15 @@ abstract contract TokenInterface {
|
||||
/// @param _to The address of the recipient
|
||||
/// @param _amount The amount of tokens to be transferred
|
||||
/// @return success Whether the transfer was successful or not
|
||||
function transferFrom(address _from, address _to, uint256 _amount) public returns (bool success);
|
||||
function transferFrom(address _from, address _to, uint256 _amount) public
|
||||
virtual returns (bool success);
|
||||
|
||||
/// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on
|
||||
/// its behalf
|
||||
/// @param _spender The address of the account able to transfer the tokens
|
||||
/// @param _amount The amount of tokens to be approved for transfer
|
||||
/// @return success Whether the approval was successful or not
|
||||
function approve(address _spender, uint256 _amount) public returns (bool success);
|
||||
function approve(address _spender, uint256 _amount) public virtual returns (bool success);
|
||||
|
||||
/// @param _owner The address of the account owning tokens
|
||||
/// @param _spender The address of the account able to transfer the tokens
|
||||
@ -75,7 +76,7 @@ abstract contract TokenInterface {
|
||||
function allowance(
|
||||
address _owner,
|
||||
address _spender
|
||||
) public view returns (uint256 remaining);
|
||||
) public virtual view returns (uint256 remaining);
|
||||
|
||||
event Transfer(address indexed _from, address indexed _to, uint256 _amount);
|
||||
event Approval(
|
||||
@ -98,7 +99,7 @@ contract Token is TokenInterface {
|
||||
return balances[_owner];
|
||||
}
|
||||
|
||||
function transfer(address _to, uint256 _amount) public override returns (bool success) {
|
||||
function transfer(address _to, uint256 _amount) public virtual override returns (bool success) {
|
||||
if (balances[msg.sender] >= _amount && _amount > 0) {
|
||||
balances[msg.sender] -= _amount;
|
||||
balances[_to] += _amount;
|
||||
@ -113,7 +114,7 @@ contract Token is TokenInterface {
|
||||
address _from,
|
||||
address _to,
|
||||
uint256 _amount
|
||||
) public override returns (bool success) {
|
||||
) public virtual override returns (bool success) {
|
||||
|
||||
if (balances[_from] >= _amount
|
||||
&& allowed[_from][msg.sender] >= _amount
|
||||
|
@ -65,15 +65,15 @@ abstract contract TokenCreationInterface {
|
||||
/// @notice Create Token with `_tokenHolder` as the initial owner of the Token
|
||||
/// @param _tokenHolder The address of the Tokens's recipient
|
||||
/// @return Whether the token creation was successful
|
||||
function createTokenProxy(address payable _tokenHolder) payable public returns (bool success);
|
||||
function createTokenProxy(address payable _tokenHolder) payable virtual public returns (bool success);
|
||||
|
||||
/// @notice Refund `msg.sender` in the case the Token Creation did
|
||||
/// not reach its minimum fueling goal
|
||||
function refund() public;
|
||||
function refund() virtual public;
|
||||
|
||||
/// @return The divisor used to calculate the token creation rate during
|
||||
/// the creation phase
|
||||
function divisor() public view returns (uint divisor);
|
||||
function divisor() public virtual view returns (uint divisor);
|
||||
|
||||
event FuelingToDate(uint value);
|
||||
event CreatedToken(address indexed to, uint amount);
|
||||
@ -151,6 +151,6 @@ override returns (bool success) {
|
||||
return 30;
|
||||
}
|
||||
}
|
||||
receive() external payable {
|
||||
receive() external virtual payable {
|
||||
}
|
||||
}
|
||||
|
@ -212,14 +212,14 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources_imports)
|
||||
char const* sourceCodeA = R"(
|
||||
pragma solidity >=0.0;
|
||||
contract A {
|
||||
function g(function(uint) external returns (uint) x) public {}
|
||||
function g(function(uint) external returns (uint) x) public virtual {}
|
||||
}
|
||||
)";
|
||||
char const* sourceCodeB = R"(
|
||||
pragma solidity >=0.0;
|
||||
import "./A";
|
||||
contract B is A {
|
||||
function g(function(uint) external returns (uint) x) public override {}
|
||||
function g(function(uint) external returns (uint) x) public virtual override {}
|
||||
}
|
||||
)";
|
||||
char const* sourceCodeC = R"(
|
||||
|
@ -2110,7 +2110,7 @@ BOOST_AUTO_TEST_CASE(virtual_function_calls)
|
||||
char const* sourceCode = R"(
|
||||
contract Base {
|
||||
function f() public returns (uint i) { return g(); }
|
||||
function g() public returns (uint i) { return 1; }
|
||||
function g() public virtual returns (uint i) { return 1; }
|
||||
}
|
||||
contract Derived is Base {
|
||||
function g() public override returns (uint i) { return 2; }
|
||||
@ -2174,8 +2174,8 @@ BOOST_AUTO_TEST_CASE(single_copy_with_multiple_inheritance)
|
||||
BOOST_AUTO_TEST_CASE(explicit_base_class)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract BaseBase { function g() public returns (uint r) { return 1; } }
|
||||
contract Base is BaseBase { function g() public override returns (uint r) { return 2; } }
|
||||
contract BaseBase { function g() public virtual returns (uint r) { return 1; } }
|
||||
contract Base is BaseBase { function g() public virtual override returns (uint r) { return 2; } }
|
||||
contract Derived is Base {
|
||||
function f() public returns (uint r) { return BaseBase.g(); }
|
||||
function g() public override returns (uint r) { return 3; }
|
||||
@ -2236,7 +2236,7 @@ BOOST_AUTO_TEST_CASE(virtual_function_usage_in_constructor_arguments)
|
||||
constructor(uint a) public {
|
||||
m_a = a;
|
||||
}
|
||||
function overridden() public returns (uint r) { return 1; }
|
||||
function overridden() public virtual returns (uint r) { return 1; }
|
||||
function g() public returns (uint r) { return overridden(); }
|
||||
}
|
||||
contract Base is BaseBase(BaseBase.g()) {
|
||||
@ -2350,8 +2350,8 @@ BOOST_AUTO_TEST_CASE(function_modifier_calling_functions_in_creation_context)
|
||||
constructor() mod1 public { f1(); }
|
||||
function f1() mod2 public { data |= 0x1; }
|
||||
function f2() public { data |= 0x20; }
|
||||
function f3() public { }
|
||||
modifier mod1 { f2(); _; }
|
||||
function f3() public virtual { }
|
||||
modifier mod1 virtual { f2(); _; }
|
||||
modifier mod2 { f3(); if (false) _; }
|
||||
function getData() public returns (uint r) { return data; }
|
||||
}
|
||||
@ -2482,9 +2482,9 @@ BOOST_AUTO_TEST_CASE(crazy_elementary_typenames_on_stack)
|
||||
BOOST_AUTO_TEST_CASE(super)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract A { function f() public returns (uint r) { return 1; } }
|
||||
contract B is A { function f() public override returns (uint r) { return super.f() | 2; } }
|
||||
contract C is A { function f() public override returns (uint r) { return super.f() | 4; } }
|
||||
contract A { function f() public virtual returns (uint r) { return 1; } }
|
||||
contract B is A { function f() public virtual override returns (uint r) { return super.f() | 2; } }
|
||||
contract C is A { function f() public virtual override returns (uint r) { return super.f() | 4; } }
|
||||
contract D is B, C { function f() public override(B, C) returns (uint r) { return super.f() | 8; } }
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "D");
|
||||
@ -2494,9 +2494,9 @@ BOOST_AUTO_TEST_CASE(super)
|
||||
BOOST_AUTO_TEST_CASE(super_in_constructor)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract A { function f() public returns (uint r) { return 1; } }
|
||||
contract B is A { function f() public override returns (uint r) { return super.f() | 2; } }
|
||||
contract C is A { function f() public override returns (uint r) { return super.f() | 4; } }
|
||||
contract A { function f() public virtual returns (uint r) { return 1; } }
|
||||
contract B is A { function f() public virtual override returns (uint r) { return super.f() | 2; } }
|
||||
contract C is A { function f() public virtual override returns (uint r) { return super.f() | 4; } }
|
||||
contract D is B, C { uint data; constructor() public { data = super.f() | 8; } function f() public override (B, C) returns (uint r) { return data; } }
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "D");
|
||||
@ -5969,11 +5969,11 @@ BOOST_AUTO_TEST_CASE(proper_order_of_overwriting_of_attributes)
|
||||
// bug #1798
|
||||
char const* sourceCode = R"(
|
||||
contract init {
|
||||
function isOk() public returns (bool) { return false; }
|
||||
function isOk() public virtual returns (bool) { return false; }
|
||||
bool public ok = false;
|
||||
}
|
||||
contract fix {
|
||||
function isOk() public returns (bool) { return true; }
|
||||
function isOk() public virtual returns (bool) { return true; }
|
||||
bool public ok = true;
|
||||
}
|
||||
|
||||
@ -7944,7 +7944,7 @@ BOOST_AUTO_TEST_CASE(state_variable_local_variable_mixture)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(inherited_function) {
|
||||
char const* sourceCode = R"(
|
||||
contract A { function f() internal returns (uint) { return 1; } }
|
||||
contract A { function f() virtual internal returns (uint) { return 1; } }
|
||||
contract B is A {
|
||||
function f() internal override returns (uint) { return 2; }
|
||||
function g() public returns (uint) {
|
||||
@ -7959,7 +7959,7 @@ BOOST_AUTO_TEST_CASE(inherited_function) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(inherited_function_calldata_memory) {
|
||||
char const* sourceCode = R"(
|
||||
contract A { function f(uint[] calldata a) external returns (uint) { return a[0]; } }
|
||||
contract A { function f(uint[] calldata a) virtual external returns (uint) { return a[0]; } }
|
||||
contract B is A {
|
||||
function f(uint[] memory a) public override returns (uint) { return a[1]; }
|
||||
function g() public returns (uint) {
|
||||
@ -14439,7 +14439,7 @@ BOOST_AUTO_TEST_CASE(external_public_override)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract A {
|
||||
function f() external returns (uint) { return 1; }
|
||||
function f() external virtual returns (uint) { return 1; }
|
||||
}
|
||||
contract B is A {
|
||||
function f() public override returns (uint) { return 2; }
|
||||
@ -14605,7 +14605,7 @@ BOOST_AUTO_TEST_CASE(contract_name)
|
||||
string public nameAccessor = type(C).name;
|
||||
string public constant constantNameAccessor = type(C).name;
|
||||
|
||||
function name() public pure returns (string memory) {
|
||||
function name() public virtual pure returns (string memory) {
|
||||
return type(C).name;
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract)
|
||||
{
|
||||
SourceUnit const* sourceUnit = nullptr;
|
||||
char const* text = R"(
|
||||
abstract contract base { function foo() public; }
|
||||
abstract contract base { function foo() public virtual; }
|
||||
contract derived is base { function foo() public override {} }
|
||||
)";
|
||||
sourceUnit = parseAndAnalyse(text);
|
||||
|
@ -1,11 +1,11 @@
|
||||
contract BaseBase {
|
||||
uint public x;
|
||||
uint public y;
|
||||
function init(uint a, uint b) public {
|
||||
function init(uint a, uint b) public virtual {
|
||||
x = b;
|
||||
y = a;
|
||||
}
|
||||
function init(uint a) public {
|
||||
function init(uint a) public virtual {
|
||||
x = a + 1;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ contract X {
|
||||
function f() public returns (uint x) {
|
||||
x = g();
|
||||
}
|
||||
function g() public returns (uint x) {
|
||||
function g() public virtual returns (uint x) {
|
||||
x = 2;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ pragma experimental SMTChecker;
|
||||
contract A {
|
||||
uint x;
|
||||
|
||||
fallback () external {
|
||||
fallback () external virtual {
|
||||
assert(x == 1);
|
||||
}
|
||||
function g() public view {
|
||||
@ -21,7 +21,7 @@ contract B is A {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (114-128): Assertion violation happens here
|
||||
// Warning: (163-177): Assertion violation happens here
|
||||
// Warning: (280-294): Assertion violation happens here
|
||||
// Warning: (163-177): Assertion violation happens here
|
||||
// Warning: (122-136): Assertion violation happens here
|
||||
// Warning: (171-185): Assertion violation happens here
|
||||
// Warning: (288-302): Assertion violation happens here
|
||||
// Warning: (171-185): Assertion violation happens here
|
||||
|
@ -4,7 +4,7 @@ pragma experimental SMTChecker;
|
||||
contract A {
|
||||
uint x;
|
||||
|
||||
function f() public view {
|
||||
function f() public virtual view {
|
||||
assert(x == 1);
|
||||
}
|
||||
function g() public view {
|
||||
@ -19,7 +19,7 @@ contract B is A {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (113-127): Assertion violation happens here
|
||||
// Warning: (162-176): Assertion violation happens here
|
||||
// Warning: (268-282): Assertion violation happens here
|
||||
// Warning: (162-176): Assertion violation happens here
|
||||
// Warning: (121-135): Assertion violation happens here
|
||||
// Warning: (170-184): Assertion violation happens here
|
||||
// Warning: (276-290): Assertion violation happens here
|
||||
// Warning: (170-184): Assertion violation happens here
|
||||
|
@ -4,7 +4,7 @@ pragma experimental SMTChecker;
|
||||
contract A {
|
||||
uint x;
|
||||
|
||||
function f() public view {
|
||||
function f() public virtual view {
|
||||
assert(x == 1);
|
||||
}
|
||||
function g() public view {
|
||||
@ -21,7 +21,7 @@ contract B is A {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (113-127): Assertion violation happens here
|
||||
// Warning: (162-176): Assertion violation happens here
|
||||
// Warning: (278-292): Assertion violation happens here
|
||||
// Warning: (162-176): Assertion violation happens here
|
||||
// Warning: (121-135): Assertion violation happens here
|
||||
// Warning: (170-184): Assertion violation happens here
|
||||
// Warning: (286-300): Assertion violation happens here
|
||||
// Warning: (170-184): Assertion violation happens here
|
||||
|
@ -4,7 +4,7 @@ pragma experimental SMTChecker;
|
||||
contract A {
|
||||
uint x;
|
||||
|
||||
function f() public view {
|
||||
function f() public virtual view {
|
||||
assert(x == 1);
|
||||
}
|
||||
function g() public view {
|
||||
@ -16,7 +16,7 @@ contract A {
|
||||
contract B is A {
|
||||
uint y;
|
||||
|
||||
function f() public view override {
|
||||
function f() public view virtual override {
|
||||
assert(x == 0);
|
||||
}
|
||||
function h() public view {
|
||||
@ -36,12 +36,12 @@ contract C is B {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (113-127): Assertion violation happens here
|
||||
// Warning: (162-176): Assertion violation happens here
|
||||
// Warning: (280-294): Assertion violation happens here
|
||||
// Warning: (329-343): Assertion violation happens here
|
||||
// Warning: (162-176): Assertion violation happens here
|
||||
// Warning: (452-466): Assertion violation happens here
|
||||
// Warning: (501-515): Assertion violation happens here
|
||||
// Warning: (329-343): Assertion violation happens here
|
||||
// Warning: (162-176): Assertion violation happens here
|
||||
// Warning: (121-135): Assertion violation happens here
|
||||
// Warning: (170-184): Assertion violation happens here
|
||||
// Warning: (296-310): Assertion violation happens here
|
||||
// Warning: (345-359): Assertion violation happens here
|
||||
// Warning: (170-184): Assertion violation happens here
|
||||
// Warning: (468-482): Assertion violation happens here
|
||||
// Warning: (517-531): Assertion violation happens here
|
||||
// Warning: (345-359): Assertion violation happens here
|
||||
// Warning: (170-184): Assertion violation happens here
|
||||
|
@ -4,7 +4,7 @@ pragma experimental SMTChecker;
|
||||
contract A {
|
||||
uint x;
|
||||
|
||||
receive () external payable {
|
||||
receive () external virtual payable {
|
||||
assert(x == 1);
|
||||
}
|
||||
function g() public view {
|
||||
@ -21,7 +21,7 @@ contract B is A {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (120-134): Assertion violation happens here
|
||||
// Warning: (169-183): Assertion violation happens here
|
||||
// Warning: (292-306): Assertion violation happens here
|
||||
// Warning: (169-183): Assertion violation happens here
|
||||
// Warning: (128-142): Assertion violation happens here
|
||||
// Warning: (177-191): Assertion violation happens here
|
||||
// Warning: (300-314): Assertion violation happens here
|
||||
// Warning: (177-191): Assertion violation happens here
|
||||
|
@ -1,5 +1,5 @@
|
||||
contract C {
|
||||
fallback() external {}
|
||||
fallback() virtual external {}
|
||||
}
|
||||
contract D is C {
|
||||
fallback() override external {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
contract C {
|
||||
fallback() external {}
|
||||
fallback() virtual external {}
|
||||
}
|
||||
contract D is C {
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
contract C {
|
||||
fallback() external {}
|
||||
fallback() virtual external {}
|
||||
}
|
||||
contract D is C {
|
||||
fallback() external {}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (58-80): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (66-88): Overriding function is missing 'override' specifier.
|
||||
|
@ -1,5 +1,5 @@
|
||||
contract C {
|
||||
fallback() external {}
|
||||
fallback() virtual external {}
|
||||
}
|
||||
contract D is C {
|
||||
}
|
||||
@ -7,4 +7,4 @@ contract E is D {
|
||||
fallback() external {}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (78-100): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (86-108): Overriding function is missing 'override' specifier.
|
||||
|
@ -1,5 +1,5 @@
|
||||
contract C {
|
||||
receive() external payable {}
|
||||
receive() virtual external payable {}
|
||||
}
|
||||
contract D is C {
|
||||
receive() override external payable {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
contract C {
|
||||
receive() external payable {}
|
||||
receive() virtual external payable {}
|
||||
}
|
||||
contract D is C {
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
contract C {
|
||||
receive() external payable {}
|
||||
receive() virtual external payable {}
|
||||
}
|
||||
contract D is C {
|
||||
receive() external payable {}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (65-94): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (73-102): Overriding function is missing 'override' specifier.
|
||||
|
@ -1,5 +1,5 @@
|
||||
contract C {
|
||||
receive() external payable {}
|
||||
receive() virtual external payable {}
|
||||
}
|
||||
contract D is C {
|
||||
}
|
||||
@ -7,4 +7,4 @@ contract E is D {
|
||||
receive() external payable {}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (85-114): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (93-122): Overriding function is missing 'override' specifier.
|
||||
|
@ -0,0 +1,5 @@
|
||||
interface I {
|
||||
function foo() virtual external;
|
||||
}
|
||||
// ----
|
||||
// Warning: (15-47): Interface functions are implicitly "virtual"
|
@ -1,5 +1,5 @@
|
||||
contract B { function f() public {} }
|
||||
contract B { function f() virtual public {} }
|
||||
contract C is B { function f() public view {} }
|
||||
// ----
|
||||
// TypeError: (56-83): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (56-83): Overriding function changes state mutability from "nonpayable" to "view".
|
||||
// TypeError: (64-91): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (64-91): Overriding function changes state mutability from "nonpayable" to "view".
|
||||
|
@ -1,9 +1,9 @@
|
||||
contract A {
|
||||
uint dummy;
|
||||
function f(uint[] calldata) external pure {}
|
||||
function g(uint[] calldata) external view { dummy; }
|
||||
function h(uint[] calldata) external { dummy = 42; }
|
||||
function i(uint[] calldata) external payable {}
|
||||
function f(uint[] calldata) external virtual pure {}
|
||||
function g(uint[] calldata) external virtual view { dummy; }
|
||||
function h(uint[] calldata) external virtual { dummy = 42; }
|
||||
function i(uint[] calldata) external virtual payable {}
|
||||
}
|
||||
contract B is A {
|
||||
function f(uint[] memory) public override pure {}
|
||||
|
@ -1,9 +1,9 @@
|
||||
contract A {
|
||||
uint dummy;
|
||||
function f(uint[] calldata) external pure {}
|
||||
function g(uint[] calldata) external view { dummy; }
|
||||
function h(uint[] calldata) external { dummy = 42; }
|
||||
function i(uint[] calldata) external payable {}
|
||||
function f(uint[] calldata) external virtual pure {}
|
||||
function g(uint[] calldata) external virtual view { dummy; }
|
||||
function h(uint[] calldata) external virtual { dummy = 42; }
|
||||
function i(uint[] calldata) external virtual payable {}
|
||||
}
|
||||
contract B is A {
|
||||
function f(uint[] calldata) external override pure {}
|
||||
@ -16,7 +16,7 @@ contract B is A {
|
||||
function i(uint[] memory) public override payable {}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError: (268-321): Function with same name and arguments defined twice.
|
||||
// DeclarationError: (326-387): Function with same name and arguments defined twice.
|
||||
// DeclarationError: (392-453): Function with same name and arguments defined twice.
|
||||
// DeclarationError: (458-514): Function with same name and arguments defined twice.
|
||||
// DeclarationError: (300-353): Function with same name and arguments defined twice.
|
||||
// DeclarationError: (358-419): Function with same name and arguments defined twice.
|
||||
// DeclarationError: (424-485): Function with same name and arguments defined twice.
|
||||
// DeclarationError: (490-546): Function with same name and arguments defined twice.
|
||||
|
@ -2,10 +2,10 @@ pragma experimental ABIEncoderV2;
|
||||
contract A {
|
||||
uint dummy;
|
||||
struct S { int a; }
|
||||
function f(S calldata) external pure {}
|
||||
function g(S calldata) external view { dummy; }
|
||||
function h(S calldata) external { dummy = 42; }
|
||||
function i(S calldata) external payable {}
|
||||
function f(S calldata) external virtual pure {}
|
||||
function g(S calldata) external virtual view { dummy; }
|
||||
function h(S calldata) external virtual { dummy = 42; }
|
||||
function i(S calldata) external virtual payable {}
|
||||
}
|
||||
contract B is A {
|
||||
function f(S memory) public override pure {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
contract A {
|
||||
function f() external pure {}
|
||||
function f() external virtual pure {}
|
||||
}
|
||||
contract B is A {
|
||||
function f() public override pure {
|
||||
|
@ -0,0 +1,7 @@
|
||||
contract C {
|
||||
function() external virtual fp;
|
||||
function() external override fp2;
|
||||
function() external override virtual fp3;
|
||||
}
|
||||
// ----
|
||||
// ParserError: (34-41): Expected identifier but got 'virtual'
|
@ -1,7 +1,7 @@
|
||||
abstract contract A {
|
||||
int public testvar;
|
||||
function test() internal returns (uint256);
|
||||
function test2() internal returns (uint256);
|
||||
function test() internal virtual returns (uint256);
|
||||
function test2() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract X is A {
|
||||
int public override testvar;
|
||||
|
@ -1,14 +1,14 @@
|
||||
abstract contract A {
|
||||
int public testvar;
|
||||
function foo() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract B {
|
||||
function foo() internal returns (uint256);
|
||||
function test() internal returns (uint256);
|
||||
function test() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract X is A, B {
|
||||
int public override testvar;
|
||||
function test() internal override returns (uint256);
|
||||
}
|
||||
// ----
|
||||
// TypeError: (202-317): Derived contract must override function "foo". Function with the same name and parameter types defined in two or more base classes.
|
||||
// TypeError: (218-333): Derived contract must override function "foo". Function with the same name and parameter types defined in two or more base classes.
|
||||
|
@ -1,17 +1,17 @@
|
||||
abstract contract A {
|
||||
function foo() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
}
|
||||
|
||||
abstract contract B is A {
|
||||
function foo() internal override returns (uint256);
|
||||
function foo() internal override virtual returns (uint256);
|
||||
}
|
||||
|
||||
abstract contract C is B {
|
||||
function foo() internal override returns (uint256);
|
||||
function foo() internal override virtual returns (uint256);
|
||||
}
|
||||
|
||||
abstract contract D is C {
|
||||
function foo() internal override returns (uint256);
|
||||
function foo() internal override virtual returns (uint256);
|
||||
}
|
||||
|
||||
abstract contract X is D {
|
||||
|
@ -0,0 +1,9 @@
|
||||
interface A {
|
||||
function test() external returns (uint256);
|
||||
function test2() external returns (uint256);
|
||||
}
|
||||
abstract contract X is A {
|
||||
function test() external override returns (uint256);
|
||||
function test2() external override(A) returns (uint256);
|
||||
}
|
||||
// ----
|
@ -0,0 +1,14 @@
|
||||
interface A {
|
||||
function test() external returns (uint256);
|
||||
function test2() external returns (uint256);
|
||||
}
|
||||
|
||||
interface B {
|
||||
function test() external returns (uint256);
|
||||
function test2() external returns (uint256);
|
||||
}
|
||||
abstract contract X is A, B {
|
||||
function test() external override(A, B) returns (uint256);
|
||||
function test2() external override(B, A) returns (uint256);
|
||||
}
|
||||
// ----
|
@ -0,0 +1,11 @@
|
||||
abstract contract A {
|
||||
function test() external virtual returns (uint256);
|
||||
function test2() external returns (uint256);
|
||||
}
|
||||
abstract contract X is A {
|
||||
function test() external returns (uint256);
|
||||
function test2() external override(A) returns (uint256);
|
||||
}
|
||||
// ----
|
||||
// TypeError: (151-194): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (76-120): Trying to override non-virtual function. Did you forget to add "virtual"?
|
@ -1,17 +1,17 @@
|
||||
abstract contract A {
|
||||
int public testvar;
|
||||
function foo() internal returns (uint256);
|
||||
function test(uint8 _a) internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
function test(uint8 _a) internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract B {
|
||||
function foo() internal returns (uint256);
|
||||
function test() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
function test() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract C {
|
||||
function foo() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract D {
|
||||
function foo() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract X is A, B, C, D {
|
||||
int public override testvar;
|
||||
|
@ -1,10 +1,10 @@
|
||||
abstract contract A {
|
||||
int public testvar;
|
||||
function foo() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
function test(uint8 _a) internal returns (uint256);
|
||||
}
|
||||
abstract contract B {
|
||||
function foo() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
}
|
||||
|
||||
abstract contract C is A {
|
||||
|
@ -1,18 +1,18 @@
|
||||
abstract contract A {
|
||||
int public testvar;
|
||||
function foo() internal returns (uint256);
|
||||
function test(uint8 _a) internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
function test(uint8 _a) internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract B {
|
||||
function foo() internal returns (uint256);
|
||||
function test() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
function test() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract C {
|
||||
function foo() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract D {
|
||||
function foo() internal returns (uint256);
|
||||
function test() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
function test() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract X is A, B, C, D {
|
||||
int public override testvar;
|
||||
@ -20,7 +20,7 @@ abstract contract X is A, B, C, D {
|
||||
function foo() internal override(A, C, B, B, B, D ,D) returns (uint256);
|
||||
}
|
||||
// ----
|
||||
// TypeError: (543-544): Duplicate contract "D" found in override list of "test".
|
||||
// TypeError: (608-609): Duplicate contract "B" found in override list of "foo".
|
||||
// TypeError: (611-612): Duplicate contract "B" found in override list of "foo".
|
||||
// TypeError: (617-618): Duplicate contract "D" found in override list of "foo".
|
||||
// TypeError: (599-600): Duplicate contract "D" found in override list of "test".
|
||||
// TypeError: (664-665): Duplicate contract "B" found in override list of "foo".
|
||||
// TypeError: (667-668): Duplicate contract "B" found in override list of "foo".
|
||||
// TypeError: (673-674): Duplicate contract "D" found in override list of "foo".
|
||||
|
@ -1,18 +1,18 @@
|
||||
abstract contract A {
|
||||
int public testvar;
|
||||
function foo() internal returns (uint256);
|
||||
function test(uint8 _a) internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
function test(uint8 _a) virtual internal returns (uint256);
|
||||
}
|
||||
abstract contract B {
|
||||
function foo() internal returns (uint256);
|
||||
function test() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
function test() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract C {
|
||||
function foo() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract D {
|
||||
function foo() internal returns (uint256);
|
||||
function test() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
function test() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract X is A, B, C, D {
|
||||
int public override testvar;
|
||||
@ -20,5 +20,5 @@ abstract contract X is A, B, C, D {
|
||||
function foo() internal override(A, C) returns (uint256);
|
||||
}
|
||||
// ----
|
||||
// TypeError: (528-545): Invalid contract specified in override list: C.
|
||||
// TypeError: (590-604): Function needs to specify overridden contracts B and D.
|
||||
// TypeError: (584-601): Invalid contract specified in override list: C.
|
||||
// TypeError: (646-660): Function needs to specify overridden contracts B and D.
|
||||
|
@ -0,0 +1,14 @@
|
||||
contract A
|
||||
{
|
||||
function foo() virtual internal {}
|
||||
}
|
||||
contract B
|
||||
{
|
||||
function foo() internal {}
|
||||
}
|
||||
contract C is A, B
|
||||
{
|
||||
function foo() internal override(A, B) {}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (65-91): Trying to override non-virtual function. Did you forget to add "virtual"?
|
@ -0,0 +1,13 @@
|
||||
contract A
|
||||
{
|
||||
function foo() virtual internal {}
|
||||
}
|
||||
contract B
|
||||
{
|
||||
function foo() internal {}
|
||||
}
|
||||
contract C is A, B
|
||||
{
|
||||
}
|
||||
// ----
|
||||
// TypeError: (94-116): Derived contract must override function "foo". Function with the same name and parameter types defined in two or more base classes.
|
@ -0,0 +1,7 @@
|
||||
abstract contract A {
|
||||
int public testvar;
|
||||
}
|
||||
abstract contract X is A {
|
||||
int public override testvar;
|
||||
}
|
||||
// ----
|
@ -1,14 +1,14 @@
|
||||
abstract contract A {
|
||||
int public testvar;
|
||||
function foo() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract B {
|
||||
function foo() internal returns (uint8);
|
||||
function test() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint8);
|
||||
function test() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract X is A, B {
|
||||
int public override testvar;
|
||||
function test() internal override returns (uint256);
|
||||
}
|
||||
// ----
|
||||
// TypeError: (200-315): Derived contract must override function "foo". Function with the same name and parameter types defined in two or more base classes.
|
||||
// TypeError: (224-339): Derived contract must override function "foo". Function with the same name and parameter types defined in two or more base classes.
|
||||
|
@ -1,13 +1,13 @@
|
||||
contract I {
|
||||
function set() public {}
|
||||
function set() public virtual {}
|
||||
}
|
||||
contract A is I {
|
||||
uint a;
|
||||
function set() public override { a = 1; super.set(); a = 2; }
|
||||
function set() public virtual override { a = 1; super.set(); a = 2; }
|
||||
}
|
||||
contract B is I {
|
||||
uint b;
|
||||
function set() public override { b = 1; super.set(); b = 2; }
|
||||
function set() public virtual override { b = 1; super.set(); b = 2; }
|
||||
|
||||
}
|
||||
contract X is A, B {
|
||||
|
@ -1,8 +1,8 @@
|
||||
contract I {
|
||||
function f() external {}
|
||||
function f() external virtual {}
|
||||
}
|
||||
contract A is I {
|
||||
function f() external override {}
|
||||
function f() external virtual override {}
|
||||
}
|
||||
contract B is I {}
|
||||
contract C is A, B {
|
||||
|
@ -1,17 +1,17 @@
|
||||
abstract contract A {
|
||||
int public testvar;
|
||||
function foo() internal returns (uint256);
|
||||
function test(uint8 _a) internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
function test(uint8 _a) internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract B {
|
||||
function foo() internal returns (uint256);
|
||||
function test() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
function test() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract C {
|
||||
function foo() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract D {
|
||||
function foo() internal returns (uint256);
|
||||
function foo() internal virtual returns (uint256);
|
||||
}
|
||||
abstract contract X is A, B, C, D {
|
||||
struct MyStruct { int abc; }
|
||||
@ -22,5 +22,5 @@ abstract contract X is A, B, C, D {
|
||||
function foo() internal override(MyStruct, ENUM, A, B, C, D) returns (uint256);
|
||||
}
|
||||
// ----
|
||||
// TypeError: (597-605): Expected contract but got struct X.MyStruct.
|
||||
// TypeError: (607-611): Expected contract but got enum X.ENUM.
|
||||
// TypeError: (645-653): Expected contract but got struct X.MyStruct.
|
||||
// TypeError: (655-659): Expected contract but got enum X.ENUM.
|
||||
|
@ -1,5 +1,5 @@
|
||||
contract B { function f() public view {} }
|
||||
contract B { function f() virtual public view {} }
|
||||
contract C is B { function f() public {} }
|
||||
// ----
|
||||
// TypeError: (61-83): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (61-83): Overriding function changes state mutability from "view" to "nonpayable".
|
||||
// TypeError: (69-91): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (69-91): Overriding function changes state mutability from "view" to "nonpayable".
|
||||
|
@ -1,5 +1,5 @@
|
||||
contract A {
|
||||
function f() external pure {}
|
||||
function f() external virtual pure {}
|
||||
}
|
||||
contract B is A {
|
||||
function f() public override pure {
|
||||
@ -7,4 +7,4 @@ contract B is A {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (115-122): Member "f" not found or not visible after argument-dependent lookup in contract super B.
|
||||
// TypeError: (123-130): Member "f" not found or not visible after argument-dependent lookup in contract super B.
|
||||
|
@ -2,9 +2,7 @@ contract C
|
||||
{
|
||||
function foo() virtual public virtual {}
|
||||
modifier modi() virtual virtual {_;}
|
||||
int virtual public virtual variable;
|
||||
}
|
||||
// ----
|
||||
// ParserError: (44-51): Virtual already specified.
|
||||
// ParserError: (80-87): Virtual already specified.
|
||||
// ParserError: (113-120): Virtual already specified.
|
||||
|
@ -3,6 +3,4 @@ contract C
|
||||
function foo() public virtual {}
|
||||
function foo2() virtual public {}
|
||||
modifier modi() virtual {_;}
|
||||
int public virtual variable;
|
||||
int virtual public variable2;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
abstract contract base { function foo() public; }
|
||||
contract derived is base { function foo() public override {} }
|
||||
abstract contract base { function foo() public virtual; }
|
||||
contract derived is base { function foo() public virtual override {} }
|
||||
contract wrong is derived { function foo() public; }
|
||||
// ----
|
||||
// TypeError: (141-163): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (141-163): Redeclaring an already implemented function as abstract
|
||||
// TypeError: (157-179): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (157-179): Redeclaring an already implemented function as abstract
|
||||
|
@ -1,6 +1,6 @@
|
||||
contract root { function rootFunction() public {} }
|
||||
contract inter1 is root { function f() public {} }
|
||||
contract inter2 is root { function f() public {} }
|
||||
contract inter1 is root { function f() public virtual {} }
|
||||
contract inter2 is root { function f() public virtual {} }
|
||||
contract derived is root, inter2, inter1 {
|
||||
function g() public { f(); rootFunction(); }
|
||||
function f() override(inter1, inter2) public {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
contract B { function f() internal {} }
|
||||
contract B { function f() virtual internal {} }
|
||||
contract C is B { function f() public {} }
|
||||
// ----
|
||||
// TypeError: (58-80): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (58-80): Overriding function visibility differs.
|
||||
// TypeError: (66-88): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (66-88): Overriding function visibility differs.
|
||||
|
@ -1,5 +1,5 @@
|
||||
contract A { function f() public { uint8 x = C(0).g(); } }
|
||||
contract B { function f() public {} function g() public returns (uint8) {} }
|
||||
contract A { function f() public virtual { uint8 x = C(0).g(); } }
|
||||
contract B { function f() public virtual {} function g() public returns (uint8) {} }
|
||||
contract C is A, B { function f() public override (A, B) { A.f(); } }
|
||||
// ----
|
||||
// Warning: (35-42): Unused local variable.
|
||||
// Warning: (43-50): Unused local variable.
|
||||
|
@ -1,6 +1,6 @@
|
||||
contract A {
|
||||
uint x;
|
||||
fallback() external { x = 1; }
|
||||
fallback() virtual external { x = 1; }
|
||||
}
|
||||
contract C is A {
|
||||
fallback() override external { x = 2; }
|
||||
|
@ -1,8 +1,8 @@
|
||||
contract Vehicle {
|
||||
function f(bytes calldata) external returns (uint256 r) {r = 1;}
|
||||
function f(bytes calldata) external virtual returns (uint256 r) {r = 1;}
|
||||
}
|
||||
contract Bike is Vehicle {
|
||||
function f(bytes calldata) override external returns (uint256 r) {r = 42;}
|
||||
}
|
||||
// ----
|
||||
// Warning: (23-87): Function state mutability can be restricted to pure
|
||||
// Warning: (23-95): Function state mutability can be restricted to pure
|
||||
|
@ -1,8 +1,8 @@
|
||||
contract base {
|
||||
function f(uint a) public returns (uint) { }
|
||||
function f(uint a) public virtual returns (uint) { }
|
||||
}
|
||||
contract test is base {
|
||||
function f(uint a) public override returns (uint8) { }
|
||||
}
|
||||
// ----
|
||||
// TypeError: (95-149): Overriding function return types differ.
|
||||
// TypeError: (103-157): Overriding function return types differ.
|
||||
|
@ -1,5 +1,5 @@
|
||||
contract B { function f() payable public {} }
|
||||
contract B { function f() payable virtual public {} }
|
||||
contract C is B { function f() public {} }
|
||||
// ----
|
||||
// TypeError: (64-86): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (64-86): Overriding function changes state mutability from "payable" to "nonpayable".
|
||||
// TypeError: (72-94): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (72-94): Overriding function changes state mutability from "payable" to "nonpayable".
|
||||
|
@ -1,5 +1,5 @@
|
||||
contract B { function f() public {} }
|
||||
contract B { function f() virtual public {} }
|
||||
contract C is B { function f() payable public {} }
|
||||
// ----
|
||||
// TypeError: (56-86): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (56-86): Overriding function changes state mutability from "nonpayable" to "payable".
|
||||
// TypeError: (64-94): Overriding function is missing 'override' specifier.
|
||||
// TypeError: (64-94): Overriding function changes state mutability from "nonpayable" to "payable".
|
||||
|
@ -5,3 +5,4 @@ contract C is I {
|
||||
function f() public override {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
|
@ -1,8 +1,8 @@
|
||||
abstract contract a {
|
||||
function f() public;
|
||||
function f() virtual public;
|
||||
}
|
||||
contract b is a {
|
||||
function f() public override { super.f(); }
|
||||
}
|
||||
// ----
|
||||
// TypeError: (102-109): Member "f" not found or not visible after argument-dependent lookup in contract super b.
|
||||
// TypeError: (110-117): Member "f" not found or not visible after argument-dependent lookup in contract super b.
|
||||
|
@ -1,12 +1,12 @@
|
||||
abstract contract a {
|
||||
function f() public;
|
||||
function f() virtual public;
|
||||
}
|
||||
contract b is a {
|
||||
function f() public override { super.f(); }
|
||||
function f() public virtual override { super.f(); }
|
||||
}
|
||||
contract c is a,b {
|
||||
// No error here.
|
||||
function f() public override(a, b) { super.f(); }
|
||||
}
|
||||
// ----
|
||||
// TypeError: (102-109): Member "f" not found or not visible after argument-dependent lookup in contract super b.
|
||||
// TypeError: (118-125): Member "f" not found or not visible after argument-dependent lookup in contract super b.
|
||||
|
@ -4,3 +4,4 @@ interface D {
|
||||
contract C is D {
|
||||
function f() override view external {}
|
||||
}
|
||||
// ----
|
||||
|
@ -1,16 +1,16 @@
|
||||
contract D {
|
||||
uint x;
|
||||
function f() public view { x; }
|
||||
function g() public pure {}
|
||||
function f() public virtual view { x; }
|
||||
function g() public virtual pure {}
|
||||
}
|
||||
contract C1 is D {
|
||||
function f() public override {}
|
||||
function g() public override view {}
|
||||
function g() public virtual override view {}
|
||||
}
|
||||
contract C2 is D {
|
||||
function g() public override {}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (118-149): Overriding function changes state mutability from "view" to "nonpayable".
|
||||
// TypeError: (154-190): Overriding function changes state mutability from "pure" to "view".
|
||||
// TypeError: (216-247): Overriding function changes state mutability from "pure" to "nonpayable".
|
||||
// TypeError: (134-165): Overriding function changes state mutability from "view" to "nonpayable".
|
||||
// TypeError: (170-214): Overriding function changes state mutability from "pure" to "view".
|
||||
// TypeError: (240-271): Overriding function changes state mutability from "pure" to "nonpayable".
|
||||
|
@ -1,6 +1,6 @@
|
||||
contract D {
|
||||
uint x;
|
||||
function f() public { x = 2; }
|
||||
function f() virtual public { x = 2; }
|
||||
}
|
||||
contract C is D {
|
||||
function f() public override {}
|
||||
|
Loading…
Reference in New Issue
Block a user