mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Restrict mobile types of function types.
Move ternary tests to semanticTests
This commit is contained in:
parent
2c82873a2c
commit
110e2a656d
@ -30,6 +30,7 @@ Bugfixes:
|
|||||||
* SMTChecker: Fix false negative when a verification target can be violated only by trusted external call from another public function.
|
* SMTChecker: Fix false negative when a verification target can be violated only by trusted external call from another public function.
|
||||||
* SMTChecker: Fix internal error caused by using external identifier to encode member access to functions that take an internal function as a parameter.
|
* SMTChecker: Fix internal error caused by using external identifier to encode member access to functions that take an internal function as a parameter.
|
||||||
* Standard JSON Interface: Fix an incomplete AST being returned when analysis is interrupted by certain kinds of fatal errors.
|
* Standard JSON Interface: Fix an incomplete AST being returned when analysis is interrupted by certain kinds of fatal errors.
|
||||||
|
* Type Checker: Disallow using certain unassignable function types in complex expressions.
|
||||||
* Type Checker: Function declaration types referring to different declarations are no longer convertible to each other.
|
* Type Checker: Function declaration types referring to different declarations are no longer convertible to each other.
|
||||||
* Yul Optimizer: Ensure that the assignment of memory slots for variables moved to memory does not depend on AST IDs that may depend on whether additional files are included during compilation.
|
* Yul Optimizer: Ensure that the assignment of memory slots for variables moved to memory does not depend on AST IDs that may depend on whether additional files are included during compilation.
|
||||||
* Yul Optimizer: Fix ``FullInliner`` step not ignoring code that is not in expression-split form.
|
* Yul Optimizer: Fix ``FullInliner`` step not ignoring code that is not in expression-split form.
|
||||||
|
@ -3472,7 +3472,11 @@ Type const* FunctionType::mobileType() const
|
|||||||
if (valueSet() || gasSet() || saltSet() || hasBoundFirstArgument())
|
if (valueSet() || gasSet() || saltSet() || hasBoundFirstArgument())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// return function without parameter names
|
// Special function types do not get a mobile type, such that they cannot be used in complex expressions.
|
||||||
|
if (m_kind != FunctionType::Kind::Internal && m_kind != FunctionType::Kind::External && m_kind != FunctionType::Kind::DelegateCall)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// return function without parameter names and without declaration
|
||||||
return TypeProvider::function(
|
return TypeProvider::function(
|
||||||
m_parameterTypes,
|
m_parameterTypes,
|
||||||
m_returnParameterTypes,
|
m_returnParameterTypes,
|
||||||
@ -3480,7 +3484,7 @@ Type const* FunctionType::mobileType() const
|
|||||||
strings(m_returnParameterNames.size()),
|
strings(m_returnParameterNames.size()),
|
||||||
m_kind,
|
m_kind,
|
||||||
m_stateMutability,
|
m_stateMutability,
|
||||||
m_declaration,
|
nullptr,
|
||||||
Options::fromFunctionType(*this)
|
Options::fromFunctionType(*this)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
contract C {
|
||||||
|
function f() public {}
|
||||||
|
function g() public {}
|
||||||
|
function h(bool c) public returns (bytes4) {
|
||||||
|
return (c ? this.f : this.g).selector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000
|
||||||
|
// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000
|
@ -0,0 +1,19 @@
|
|||||||
|
contract A {
|
||||||
|
function f() public {}
|
||||||
|
function g() public {}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
A a = new A();
|
||||||
|
|
||||||
|
function getContract() public view returns (A) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
function test(bool b) public view returns (bytes4) {
|
||||||
|
return (b ? getContract().f : getContract().g).selector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// test(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000
|
||||||
|
// test(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000
|
@ -0,0 +1,10 @@
|
|||||||
|
contract C {
|
||||||
|
function f() internal pure returns(uint256) { return 1;}
|
||||||
|
function g() internal pure returns(uint256) { return 2; }
|
||||||
|
function test(bool b) public returns(uint256) {
|
||||||
|
return (b ? C.f : C.g)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// test(bool): true -> 1
|
||||||
|
// test(bool): false -> 2
|
@ -0,0 +1,13 @@
|
|||||||
|
library L {
|
||||||
|
function f() internal pure returns(uint256){ return 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
function g() internal pure returns(uint256) { return 2; }
|
||||||
|
function test(bool b) public returns(uint256) {
|
||||||
|
return (b ? L.f : C.g)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// test(bool): true -> 1
|
||||||
|
// test(bool): false -> 2
|
@ -0,0 +1,10 @@
|
|||||||
|
contract C {
|
||||||
|
function f() public pure returns(uint256) { return 1; }
|
||||||
|
function g() public pure returns(uint256) { return 2; }
|
||||||
|
function test(bool b) public returns(uint256) {
|
||||||
|
return (b ? C.f : C.g)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// test(bool): true -> 1
|
||||||
|
// test(bool): false -> 2
|
@ -0,0 +1,11 @@
|
|||||||
|
error MyCustomError(uint, bool);
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
function f() pure public {
|
||||||
|
true ? MyCustomError : MyCustomError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// TypeError 9717: (93-106): Invalid mobile type in true expression.
|
||||||
|
// TypeError 3703: (109-122): Invalid mobile type in false expression.
|
@ -1,18 +0,0 @@
|
|||||||
error MyCustomError(uint, bool);
|
|
||||||
error MyCustomError2(uint, bool);
|
|
||||||
error MyCustomError3(uint, bool, bool);
|
|
||||||
|
|
||||||
contract C {
|
|
||||||
function f() pure public {
|
|
||||||
true ? MyCustomError : MyCustomError;
|
|
||||||
true ? MyCustomError : MyCustomError2;
|
|
||||||
true ? MyCustomError : MyCustomError3;
|
|
||||||
true ? MyCustomError : true;
|
|
||||||
true ? true : MyCustomError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----
|
|
||||||
// TypeError 1080: (253-290): True expression's type error MyCustomError(uint256,bool) does not match false expression's type error MyCustomError3(uint256,bool,bool).
|
|
||||||
// TypeError 1080: (300-327): True expression's type error MyCustomError(uint256,bool) does not match false expression's type bool.
|
|
||||||
// TypeError 1080: (337-364): True expression's type bool does not match false expression's type error MyCustomError(uint256,bool).
|
|
@ -0,0 +1,10 @@
|
|||||||
|
contract C {
|
||||||
|
event MyCustomEvent(uint);
|
||||||
|
function f() pure public {
|
||||||
|
true ? MyCustomEvent : MyCustomEvent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// TypeError 9717: (90-103): Invalid mobile type in true expression.
|
||||||
|
// TypeError 3703: (106-119): Invalid mobile type in false expression.
|
@ -1,17 +0,0 @@
|
|||||||
contract C {
|
|
||||||
event MyCustomEvent(uint);
|
|
||||||
event MyCustomEvent2(uint);
|
|
||||||
event MyCustomEvent3(uint, bool);
|
|
||||||
function f() pure public {
|
|
||||||
true ? MyCustomEvent : MyCustomEvent;
|
|
||||||
true ? MyCustomEvent : MyCustomEvent2;
|
|
||||||
true ? MyCustomEvent : MyCustomEvent3;
|
|
||||||
true ? MyCustomEvent : true;
|
|
||||||
true ? true : MyCustomEvent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----
|
|
||||||
// TypeError 1080: (246-283): True expression's type event MyCustomEvent(uint256) does not match false expression's type event MyCustomEvent3(uint256,bool).
|
|
||||||
// TypeError 1080: (293-320): True expression's type event MyCustomEvent(uint256) does not match false expression's type bool.
|
|
||||||
// TypeError 1080: (330-357): True expression's type bool does not match false expression's type event MyCustomEvent(uint256).
|
|
@ -0,0 +1,8 @@
|
|||||||
|
contract C {
|
||||||
|
function f() public pure returns (uint x) {
|
||||||
|
x = (true ? addmod : addmod)(3, 4, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9717: (81-87): Invalid mobile type in true expression.
|
||||||
|
// TypeError 3703: (90-96): Invalid mobile type in false expression.
|
@ -0,0 +1,10 @@
|
|||||||
|
contract C {
|
||||||
|
function f() external pure { }
|
||||||
|
function g() external pure { }
|
||||||
|
function test(bool b) public returns(bytes4) {
|
||||||
|
(b ? C.f : C.g).selector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9717: (147-150): Invalid mobile type in true expression.
|
||||||
|
// TypeError 3703: (153-156): Invalid mobile type in false expression.
|
@ -0,0 +1,13 @@
|
|||||||
|
contract C {
|
||||||
|
function f() public pure { }
|
||||||
|
function g() public pure { }
|
||||||
|
}
|
||||||
|
|
||||||
|
contract A {
|
||||||
|
function test(bool b) public returns(bytes4) {
|
||||||
|
(b ? C.f : C.g).selector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9717: (159-162): Invalid mobile type in true expression.
|
||||||
|
// TypeError 3703: (165-168): Invalid mobile type in false expression.
|
@ -0,0 +1,16 @@
|
|||||||
|
contract C {
|
||||||
|
function f() external pure { }
|
||||||
|
}
|
||||||
|
|
||||||
|
contract D {
|
||||||
|
function g() external pure { }
|
||||||
|
}
|
||||||
|
|
||||||
|
contract A {
|
||||||
|
function test(bool b) public returns(bytes4) {
|
||||||
|
(b ? C.f : D.g).selector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9717: (179-182): Invalid mobile type in true expression.
|
||||||
|
// TypeError 3703: (185-188): Invalid mobile type in false expression.
|
@ -0,0 +1,16 @@
|
|||||||
|
interface I1 {
|
||||||
|
function f() external pure;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface I2 {
|
||||||
|
function g() external pure;
|
||||||
|
}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
function test(bool b) public returns(bytes4) {
|
||||||
|
(b ? I1.f : I2.g).selector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9717: (177-181): Invalid mobile type in true expression.
|
||||||
|
// TypeError 3703: (184-188): Invalid mobile type in false expression.
|
Loading…
Reference in New Issue
Block a user