Merge pull request #6320 from ethereum/callvalue_nonpayable

Inline Assembly: Issue error for callvalue in nonpayable function
This commit is contained in:
chriseth 2019-03-20 10:07:09 +01:00 committed by GitHub
commit 4d89fc1644
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 84 additions and 6 deletions

View File

@ -4,6 +4,7 @@ Language Features:
Compiler Features:
* Inline Assembly: Issue error when using ``callvalue()`` inside nonpayable function (in the same way that ``msg.value`` already does).
* Yul Optimizer: Enable stack allocation optimization by default if yul optimizer is active (disable in yulDetails).

View File

@ -112,6 +112,8 @@ private:
{
if (eth::SemanticInformation::invalidInViewFunctions(_instruction))
m_reportMutability(StateMutability::NonPayable, _location);
else if (_instruction == Instruction::CALLVALUE)
m_reportMutability(StateMutability::Payable, _location);
else if (eth::SemanticInformation::invalidInPureFunctions(_instruction))
m_reportMutability(StateMutability::View, _location);
}
@ -270,13 +272,13 @@ void ViewPureChecker::reportMutability(
if (_nestedLocation)
m_errorReporter.typeError(
_location,
SecondarySourceLocation().append("\"msg.value\" appears here inside the modifier.", *_nestedLocation),
"This modifier uses \"msg.value\" and thus the function has to be payable or internal."
SecondarySourceLocation().append("\"msg.value\" or \"callvalue()\" appear here inside the modifier.", *_nestedLocation),
"This modifier uses \"msg.value\" or \"callvalue()\" and thus the function has to be payable or internal."
);
else
m_errorReporter.typeError(
_location,
"\"msg.value\" can only be used in payable public functions. Make the function "
"\"msg.value\" and \"callvalue()\" can only be used in payable public functions. Make the function "
"\"payable\" or use an internal function to avoid this error."
);
m_errors = true;

View File

@ -3,4 +3,4 @@ contract C {
function f() costs(1 ether) public view {}
}
// ----
// TypeError: (101-115): This modifier uses "msg.value" and thus the function has to be payable or internal.
// TypeError: (101-115): This modifier uses "msg.value" or "callvalue()" and thus the function has to be payable or internal.

View File

@ -4,4 +4,4 @@ contract C {
}
}
// ----
// TypeError: (52-61): "msg.value" can only be used in payable public functions. Make the function "payable" or use an internal function to avoid this error.
// TypeError: (52-61): "msg.value" and "callvalue()" can only be used in payable public functions. Make the function "payable" or use an internal function to avoid this error.

View File

@ -0,0 +1,11 @@
contract C
{
function () external {
uint x;
assembly {
x := callvalue()
}
}
}
// ----
// TypeError: (92-103): "msg.value" and "callvalue()" can only be used in payable public functions. Make the function "payable" or use an internal function to avoid this error.

View File

@ -0,0 +1,10 @@
contract C
{
function f(uint x) public {
assembly {
x := callvalue()
}
}
}
// ----
// TypeError: (81-92): "msg.value" and "callvalue()" can only be used in payable public functions. Make the function "payable" or use an internal function to avoid this error.

View File

@ -0,0 +1,11 @@
contract C
{
function f() internal returns (uint x) {
assembly {
x := callvalue()
}
}
function g() public returns (uint) {
return f();
}
}

View File

@ -0,0 +1,14 @@
contract C
{
modifier m {
uint x;
assembly {
x := callvalue()
}
_;
}
function f() m public {
}
}
// ----
// TypeError: (99-100): This modifier uses "msg.value" or "callvalue()" and thus the function has to be payable or internal.

View File

@ -0,0 +1,9 @@
contract C
{
function () external payable {
uint x;
assembly {
x := callvalue()
}
}
}

View File

@ -0,0 +1,8 @@
contract C
{
function f(uint x) public payable {
assembly {
x := callvalue()
}
}
}

View File

@ -0,0 +1,12 @@
contract C
{
modifier m {
uint x;
assembly {
x := callvalue()
}
_;
}
function f() m public payable {
}
}

View File

@ -3,4 +3,4 @@ contract C {
function f() m(1 ether, msg.value) public view {}
}
// ----
// TypeError: (118-127): "msg.value" can only be used in payable public functions. Make the function "payable" or use an internal function to avoid this error.
// TypeError: (118-127): "msg.value" and "callvalue()" can only be used in payable public functions. Make the function "payable" or use an internal function to avoid this error.