mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Disallow specifying call options multiple times.
This commit is contained in:
parent
ce50f05fc1
commit
b287a6e995
@ -4,6 +4,7 @@ Breaking Changes:
|
||||
* Assembler: The artificial ASSIGNIMMUTABLE opcode and the corresponding builtin in the "EVM with object access" dialect of Yul take the base offset of the code to modify as additional argument.
|
||||
* Code Generator: All arithmetic is checked by default. These checks can be disabled using ``unchecked { ... }``.
|
||||
* General: Remove global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4``.
|
||||
* Type Checker: Function call options can only be given once.
|
||||
* Type System: Unary negation can only be used on signed integers, not on unsigned integers.
|
||||
* Type System: Disallow explicit conversions from negative literals and literals larger than ``type(uint160).max`` to ``address`` type.
|
||||
* Parser: Exponentiation is right associative. ``a**b**c`` is parsed as ``a**(b**c)``.
|
||||
|
@ -40,6 +40,8 @@ New Restrictions
|
||||
|
||||
The previous behaviour was likely ambiguous.
|
||||
|
||||
* Function call options can only be given once, i.e. ``c.f{gas: 10000}{value: 1}()`` is invalid and has to be changed to ``c.f{gas: 10000, value: 1}()``.
|
||||
|
||||
* The global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4`` have been removed.
|
||||
|
||||
These are low-level functions that were largely unused. Their behaviour can be accessed from inline assembly.
|
@ -2425,14 +2425,24 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions)
|
||||
return false;
|
||||
}
|
||||
|
||||
auto setCheckOption = [&](bool& _option, string const&& _name, bool _alreadySet = false)
|
||||
if (
|
||||
expressionFunctionType->valueSet() ||
|
||||
expressionFunctionType->gasSet() ||
|
||||
expressionFunctionType->saltSet()
|
||||
)
|
||||
m_errorReporter.typeError(
|
||||
1645_error,
|
||||
_functionCallOptions.location(),
|
||||
"Function call options have already been set, you have to combine them into a single "
|
||||
"{...}-option."
|
||||
);
|
||||
|
||||
auto setCheckOption = [&](bool& _option, string const& _name)
|
||||
{
|
||||
if (_option || _alreadySet)
|
||||
if (_option)
|
||||
m_errorReporter.typeError(
|
||||
9886_error,
|
||||
_functionCallOptions.location(),
|
||||
_alreadySet ?
|
||||
"Option \"" + std::move(_name) + "\" has already been set." :
|
||||
"Duplicate option \"" + std::move(_name) + "\"."
|
||||
);
|
||||
|
||||
@ -2446,7 +2456,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions)
|
||||
{
|
||||
if (kind == FunctionType::Kind::Creation)
|
||||
{
|
||||
setCheckOption(setSalt, "salt", expressionFunctionType->saltSet());
|
||||
setCheckOption(setSalt, "salt");
|
||||
expectType(*_functionCallOptions.options()[i], *TypeProvider::fixedBytes(32));
|
||||
}
|
||||
else
|
||||
@ -2484,7 +2494,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions)
|
||||
{
|
||||
expectType(*_functionCallOptions.options()[i], *TypeProvider::uint256());
|
||||
|
||||
setCheckOption(setValue, "value", expressionFunctionType->valueSet());
|
||||
setCheckOption(setValue, "value");
|
||||
}
|
||||
}
|
||||
else if (name == "gas")
|
||||
@ -2499,7 +2509,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions)
|
||||
{
|
||||
expectType(*_functionCallOptions.options()[i], *TypeProvider::uint256());
|
||||
|
||||
setCheckOption(setGas, "gas", expressionFunctionType->gasSet());
|
||||
setCheckOption(setGas, "gas");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -5,8 +5,9 @@ contract C {
|
||||
v = this.f{value: 10}(2);
|
||||
x = this.f{gas: 1000}(2, 3);
|
||||
y = this.f{gas: 1000, value: 10}(2, 3);
|
||||
z = this.f{gas: 1000}{value: 10}(2, 3);
|
||||
z = this.f{value: 10, gas: 1000}(2, 3);
|
||||
}
|
||||
function bal() external returns (uint) { return address(this).balance; }
|
||||
receive() external payable {}
|
||||
}
|
||||
// ====
|
||||
@ -14,3 +15,4 @@ contract C {
|
||||
// ----
|
||||
// (), 1 ether
|
||||
// call() -> 1, 2, 2, 2
|
||||
// bal() -> 1000000000000000000
|
||||
|
@ -12,8 +12,8 @@ contract B
|
||||
contract A {
|
||||
function f() public payable returns (uint, uint, uint) {
|
||||
B x = new B{salt: "abc", value: 3}(7);
|
||||
B y = new B{value: 3}{salt: "abc"}(8);
|
||||
B z = new B{value: 3, salt: "abc"}(9);
|
||||
B y = new B{value: 3, salt: "abc"}(8);
|
||||
B z = new B{salt: "abc", value: 3}(9);
|
||||
return (x.getBalance(), y.getBalance(), z.getBalance());
|
||||
}
|
||||
}
|
||||
|
@ -11,9 +11,8 @@ contract C {
|
||||
// ====
|
||||
// EVMVersion: >=constantinople
|
||||
// ----
|
||||
// TypeError 9886: (78-110): Option "gas" has already been set.
|
||||
// TypeError 9886: (120-154): Option "gas" has already been set.
|
||||
// TypeError 9886: (164-198): Option "value" has already been set.
|
||||
// TypeError 9886: (208-249): Option "value" has already been set.
|
||||
// TypeError 9886: (208-249): Option "gas" has already been set.
|
||||
// TypeError 9886: (259-286): Option "salt" has already been set.
|
||||
// TypeError 1645: (78-110): Function call options have already been set, you have to combine them into a single {...}-option.
|
||||
// TypeError 1645: (120-154): Function call options have already been set, you have to combine them into a single {...}-option.
|
||||
// TypeError 1645: (164-198): Function call options have already been set, you have to combine them into a single {...}-option.
|
||||
// TypeError 1645: (208-249): Function call options have already been set, you have to combine them into a single {...}-option.
|
||||
// TypeError 1645: (259-286): Function call options have already been set, you have to combine them into a single {...}-option.
|
||||
|
Loading…
Reference in New Issue
Block a user