Skip to content

Commit 424edcc

Browse files
authored
Merge pull request #11475 from ethereum/receive-override
Fix ICE related to receive function having parameters.
2 parents 9be5754 + c3eef8a commit 424edcc

File tree

14 files changed

+73
-35
lines changed

14 files changed

+73
-35
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Bugfixes:
2727
* Type Checker: Fix internal compiler error related to having mapping types in constructor parameter for abstract contracts.
2828
* Type Checker: Fix internal compiler error when attempting to use an invalid external function type on pre-byzantium EVMs.
2929
* Type Checker: Make errors about (nested) mapping type in event or error parameter into fatal type errors.
30+
* Type Checker: Fix internal compiler error when overriding receive ether function with one having different parameters during inheritance.
3031

3132

3233
AST Changes:

libsolidity/analysis/ContractLevelChecker.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ bool ContractLevelChecker::check(ContractDefinition const& _contract)
8686

8787
checkDuplicateFunctions(_contract);
8888
checkDuplicateEvents(_contract);
89+
checkReceiveFunction(_contract);
8990
m_overrideChecker.check(_contract);
9091
checkBaseConstructorArguments(_contract);
9192
checkAbstractDefinitions(_contract);
@@ -162,6 +163,35 @@ void ContractLevelChecker::checkDuplicateEvents(ContractDefinition const& _contr
162163
findDuplicateDefinitions(events);
163164
}
164165

166+
void ContractLevelChecker::checkReceiveFunction(ContractDefinition const& _contract)
167+
{
168+
for (FunctionDefinition const* function: _contract.definedFunctions())
169+
{
170+
solAssert(function, "");
171+
if (function->isReceive())
172+
{
173+
if (function->libraryFunction())
174+
m_errorReporter.declarationError(4549_error, function->location(), "Libraries cannot have receive ether functions.");
175+
176+
if (function->stateMutability() != StateMutability::Payable)
177+
m_errorReporter.declarationError(
178+
7793_error,
179+
function->location(),
180+
"Receive ether function must be payable, but is \"" +
181+
stateMutabilityToString(function->stateMutability()) +
182+
"\"."
183+
);
184+
if (function->visibility() != Visibility::External)
185+
m_errorReporter.declarationError(4095_error, function->location(), "Receive ether function must be defined as \"external\".");
186+
187+
if (!function->returnParameters().empty())
188+
m_errorReporter.fatalDeclarationError(6899_error, function->returnParameterList()->location(), "Receive ether function cannot return values.");
189+
if (!function->parameters().empty())
190+
m_errorReporter.fatalDeclarationError(6857_error, function->parameterList().location(), "Receive ether function cannot take parameters.");
191+
}
192+
}
193+
}
194+
165195
template <class T>
166196
void ContractLevelChecker::findDuplicateDefinitions(map<string, vector<T>> const& _definitions)
167197
{

libsolidity/analysis/ContractLevelChecker.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class ContractLevelChecker
6363
/// arguments and that there is at most one constructor.
6464
void checkDuplicateFunctions(ContractDefinition const& _contract);
6565
void checkDuplicateEvents(ContractDefinition const& _contract);
66+
void checkReceiveFunction(ContractDefinition const& _contract);
6667
template <class T>
6768
void findDuplicateDefinitions(std::map<std::string, std::vector<T>> const& _definitions);
6869
/// Checks for unimplemented functions and modifiers.

libsolidity/analysis/TypeChecker.cpp

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -489,8 +489,6 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
489489

490490
if (_function.isFallback())
491491
typeCheckFallbackFunction(_function);
492-
else if (_function.isReceive())
493-
typeCheckReceiveFunction(_function);
494492
else if (_function.isConstructor())
495493
typeCheckConstructor(_function);
496494

@@ -1881,30 +1879,6 @@ void TypeChecker::typeCheckFallbackFunction(FunctionDefinition const& _function)
18811879
}
18821880
}
18831881

1884-
void TypeChecker::typeCheckReceiveFunction(FunctionDefinition const& _function)
1885-
{
1886-
solAssert(_function.isReceive(), "");
1887-
1888-
if (_function.libraryFunction())
1889-
m_errorReporter.typeError(4549_error, _function.location(), "Libraries cannot have receive ether functions.");
1890-
1891-
if (_function.stateMutability() != StateMutability::Payable)
1892-
m_errorReporter.typeError(
1893-
7793_error,
1894-
_function.location(),
1895-
"Receive ether function must be payable, but is \"" +
1896-
stateMutabilityToString(_function.stateMutability()) +
1897-
"\"."
1898-
);
1899-
if (_function.visibility() != Visibility::External)
1900-
m_errorReporter.typeError(4095_error, _function.location(), "Receive ether function must be defined as \"external\".");
1901-
if (!_function.returnParameters().empty())
1902-
m_errorReporter.typeError(6899_error, _function.returnParameterList()->location(), "Receive ether function cannot return values.");
1903-
if (!_function.parameters().empty())
1904-
m_errorReporter.typeError(6857_error, _function.parameterList().location(), "Receive ether function cannot take parameters.");
1905-
}
1906-
1907-
19081882
void TypeChecker::typeCheckConstructor(FunctionDefinition const& _function)
19091883
{
19101884
solAssert(_function.isConstructor(), "");

libsolidity/analysis/TypeChecker.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ class TypeChecker: private ASTConstVisitor
9696
);
9797

9898
void typeCheckFallbackFunction(FunctionDefinition const& _function);
99-
void typeCheckReceiveFunction(FunctionDefinition const& _function);
10099
void typeCheckConstructor(FunctionDefinition const& _function);
101100

102101
/// Performs general number and type checks of arguments against function call and struct ctor FunctionCall node parameters.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
contract C {
2+
receive(bytes2) {}
3+
}
4+
contract D is C {
5+
receive() {}
6+
}
7+
// ----
8+
// SyntaxError 4937: (17-35): No visibility specified. Did you intend to add "external"?
9+
// SyntaxError 4937: (60-72): No visibility specified. Did you intend to add "external"?
10+
// DeclarationError 7793: (17-35): Receive ether function must be payable, but is "nonpayable".
11+
// DeclarationError 4095: (17-35): Receive ether function must be defined as "external".
12+
// DeclarationError 6857: (24-32): Receive ether function cannot take parameters.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
contract C {
2+
receive() external payable virtual returns(uint) {}
3+
}
4+
contract D is C {
5+
receive() external payable override {}
6+
}
7+
// ----
8+
// DeclarationError 6899: (59-65): Receive ether function cannot return values.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
interface I {
2+
receive(bytes2) external payable;
3+
}
4+
5+
interface J is I {
6+
receive() external payable override;
7+
}
8+
9+
contract C is J {
10+
receive() external payable override {}
11+
}
12+
// ----
13+
// DeclarationError 6857: (25-33): Receive ether function cannot take parameters.

test/libsolidity/syntaxTests/nameAndTypeResolution/076_receive_function_in_library.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ library C {
22
receive() external payable {}
33
}
44
// ----
5+
// DeclarationError 4549: (16-45): Libraries cannot have receive ether functions.
56
// TypeError 7708: (16-45): Library functions cannot be payable.
6-
// TypeError 4549: (16-45): Libraries cannot have receive ether functions.

test/libsolidity/syntaxTests/receiveEther/arguments.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ contract C {
22
receive(uint256) external payable {}
33
}
44
// ----
5-
// TypeError 6857: (24-33): Receive ether function cannot take parameters.
5+
// DeclarationError 6857: (24-33): Receive ether function cannot take parameters.

0 commit comments

Comments
 (0)