Additional tests for user operators with calldata and storage parameters

This commit is contained in:
wechman 2022-08-04 08:12:34 +02:00
parent b860561814
commit 4fac7b54b3
3 changed files with 119 additions and 8 deletions

View File

@ -1859,12 +1859,15 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
commonType = builtinResult.get();
else if (userDefinedOperatorResult)
{
solAssert(
userDefinedFunctionType->parameterTypes().size() == 2 &&
*userDefinedFunctionType->parameterTypes().at(0) ==
*userDefinedFunctionType->parameterTypes().at(1)
);
if (userDefinedFunctionType->returnParameterTypes().size() == 1)
if (userDefinedFunctionType->parameterTypes().size() != 2 ||
*userDefinedFunctionType->parameterTypes().at(0) != *userDefinedFunctionType->parameterTypes().at(1))
m_errorReporter.typeError(
5653_error,
_operation.location(),
"User defined operator " + string(TokenTraits::toString(_operation.getOperator())) +
" needs to have two parameters of equal type."
);
else if (userDefinedFunctionType->returnParameterTypes().size() == 1)
commonType = userDefinedFunctionType->parameterTypes().at(0);
}

View File

@ -1,4 +1,12 @@
using {add as +} for S;
using {
add as +,
sub as -,
mul as *,
div as /,
mod as %,
unsub as -,
bitnot as ~
} for S;
struct S {
uint x;
@ -9,3 +17,54 @@ function add(S calldata, S calldata) pure returns (S calldata r) {
r := 0
}
}
function sub(S calldata, uint) pure returns (S calldata r) {
assembly {
r := 0
}
}
function mul(S calldata) pure returns (S calldata r) {
assembly {
r := 0
}
}
function div(S calldata, S calldata) pure returns (uint) {
return 0;
}
function mod(S calldata, S calldata) pure {
}
function unsub(uint) pure returns (S calldata r) {
assembly {
r := 0
}
}
function bitnot(S calldata) pure {
}
function test(S calldata s) pure {
s + s;
s - s;
s * s;
s / s;
s % s;
-s;
~s;
}
// ----
// TypeError 1884: (40-43): The function "mul" needs to have two parameters of equal type to be used for the operator *.
// TypeError 7743: (54-57): The function "div" needs to return exactly one value of type S to be used for the operator /.
// TypeError 7743: (68-71): The function "mod" needs to return exactly one value of type S to be used for the operator %.
// TypeError 3100: (82-87): The function "unsub" cannot be bound to the type "struct S storage pointer" because the type cannot be implicitly converted to the first argument of the function ("uint256").
// TypeError 7743: (98-104): The function "bitnot" needs to return exactly one value of type S to be used for the operator ~.
// TypeError 5653: (747-752): User defined operator - needs to have two parameters of equal type.
// TypeError 2271: (758-763): Operator * not compatible with types struct S calldata and struct S calldata. No matching user-defined operator found.
// TypeError 3841: (769-774): User defined operator / needs to return value of type struct S calldata.
// TypeError 1208: (780-785): User defined operator % needs to return exactly one value.
// TypeError 4907: (791-793): Unary operator - cannot be applied to type struct S calldata. No matching user-defined operator found.
// TypeError 3138: (799-801): User defined operator ~ needs to return exactly one value.

View File

@ -1,4 +1,12 @@
using {add as +} for S;
using {
add as +,
sub as -,
mul as *,
div as /,
mod as %,
unsub as -,
bitnot as ~
} for S;
struct S {
uint x;
@ -8,11 +16,52 @@ function add(S storage a, S storage) pure returns (S storage) {
return a;
}
function sub(S storage a, uint) pure returns (S storage) {
return a;
}
function mul(S storage a) pure returns (S storage) {
return a;
}
function div(S storage a, S storage) pure returns (uint) {
return 0;
}
function mod(S storage a, S storage) pure {
}
function unsub(S storage a) pure {
}
function bitnot(S storage a, S storage) pure returns (S storage) {
return a;
}
contract C {
S a;
S b;
function test() public view {
a + b;
a - b;
a * b;
a / b;
a % b;
-a;
~a;
}
}
// ----
// TypeError 1884: (40-43): The function "mul" needs to have two parameters of equal type to be used for the operator *.
// TypeError 7743: (54-57): The function "div" needs to return exactly one value of type S to be used for the operator /.
// TypeError 7743: (68-71): The function "mod" needs to return exactly one value of type S to be used for the operator %.
// TypeError 7743: (82-87): The function "unsub" needs to return exactly one value of type S to be used for the operator -.
// TypeError 1147: (98-104): The function "bitnot" needs to have exactly one parameter to be used for the operator ~.
// TypeError 5653: (707-712): User defined operator - needs to have two parameters of equal type.
// TypeError 3841: (707-712): User defined operator - needs to return value of type struct S storage ref.
// TypeError 2271: (722-727): Operator * not compatible with types struct S storage ref and struct S storage ref. No matching user-defined operator found.
// TypeError 3841: (737-742): User defined operator / needs to return value of type struct S storage pointer.
// TypeError 1208: (752-757): User defined operator % needs to return exactly one value.
// TypeError 3138: (767-769): User defined operator - needs to return exactly one value.
// TypeError 4907: (779-781): Unary operator ~ cannot be applied to type struct S storage ref. No matching user-defined operator found.