Merge pull request #4481 from ethereum/disallow-throw

[BREAKING] Deprecate the throw statement
This commit is contained in:
chriseth 2018-07-16 16:25:22 +02:00 committed by GitHub
commit 29dae15c50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 112 additions and 136 deletions

View File

@ -20,6 +20,7 @@ Breaking Changes:
* General: Disallow raw ``callcode`` (was already deprecated in 0.4.12). It is still possible to use it via inline assembly.
* General: Disallow ``var`` keyword.
* General: Disallow ``sha3`` and ``suicide`` aliases.
* General: Disallow the ``throw`` statement. This was already the case in the experimental 0.5.0 mode.
* General: Disallow the ``years`` unit denomination (was already deprecated in 0.4.24)
* General: Introduce ``emit`` as a keyword instead of parsing it as identifier.
* General: New keywords: ``calldata``

View File

@ -175,18 +175,10 @@ bool SyntaxChecker::visit(Break const& _breakStatement)
bool SyntaxChecker::visit(Throw const& _throwStatement)
{
bool const v050 = m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeature::V050);
if (v050)
m_errorReporter.syntaxError(
_throwStatement.location(),
"\"throw\" is deprecated in favour of \"revert()\", \"require()\" and \"assert()\"."
);
else
m_errorReporter.warning(
_throwStatement.location(),
"\"throw\" is deprecated in favour of \"revert()\", \"require()\" and \"assert()\"."
);
m_errorReporter.syntaxError(
_throwStatement.location(),
"\"throw\" is deprecated in favour of \"revert()\", \"require()\" and \"assert()\"."
);
return true;
}

View File

@ -33,49 +33,49 @@ contract MultiSigWallet {
modifier onlyWallet() {
if (msg.sender != address(this))
throw;
revert();
_;
}
modifier ownerDoesNotExist(address owner) {
if (isOwner[owner])
throw;
revert();
_;
}
modifier ownerExists(address owner) {
if (!isOwner[owner])
throw;
revert();
_;
}
modifier transactionExists(uint transactionId) {
if (transactions[transactionId].destination == address(0))
throw;
revert();
_;
}
modifier confirmed(uint transactionId, address owner) {
if (!confirmations[transactionId][owner])
throw;
revert();
_;
}
modifier notConfirmed(uint transactionId, address owner) {
if (confirmations[transactionId][owner])
throw;
revert();
_;
}
modifier notExecuted(uint transactionId) {
if (transactions[transactionId].executed)
throw;
revert();
_;
}
modifier notNull(address _address) {
if (_address == address(0))
throw;
revert();
_;
}
@ -84,7 +84,7 @@ contract MultiSigWallet {
|| _required > ownerCount
|| _required == 0
|| ownerCount == 0)
throw;
revert();
_;
}
@ -109,7 +109,7 @@ contract MultiSigWallet {
{
for (uint i=0; i<_owners.length; i++) {
if (isOwner[_owners[i]] || _owners[i] == address(0))
throw;
revert();
isOwner[_owners[i]] = true;
}
owners = _owners;

View File

@ -27,7 +27,7 @@ contract TestToken {
returns (bool success)
{
if (balances[msg.sender] < _value) {
throw;
revert();
}
balances[msg.sender] -= _value;
balances[_to] += _value;
@ -40,7 +40,7 @@ contract TestToken {
returns (bool success)
{
if (balances[_from] < _value || allowed[_from][msg.sender] < _value) {
throw;
revert();
}
balances[_to] += _value;
balances[_from] -= _value;

View File

@ -514,7 +514,7 @@ contract provider is module, safeMath, announcementTypes {
} else if ( clients[msg.sender].providerAddress != address(0x00) ) {
clientReward = getClientReward(_limit);
} else {
throw;
revert();
}
if ( clientReward > 0 ) {
require( moduleHandler(moduleHandlerAddress).transfer(address(this), _beneficiary, clientReward, false) );

View File

@ -389,7 +389,7 @@ contract schelling is module, announcementTypes, schellingVars {
}
delete voter.status;
delete voter.roundID;
} else { throw; }
} else { revert(); }
setVoter(msg.sender, voter);
setFunds(msg.sender, funds);

View File

@ -83,14 +83,14 @@ contract MilestoneTracker {
/// @dev The following modifiers only allow specific roles to call functions
/// with these modifiers
modifier onlyRecipient { if (msg.sender != recipient) throw; _; }
modifier onlyArbitrator { if (msg.sender != arbitrator) throw; _; }
modifier onlyDonor { if (msg.sender != donor) throw; _; }
modifier onlyRecipient { if (msg.sender != recipient) revert(); _; }
modifier onlyArbitrator { if (msg.sender != arbitrator) revert(); _; }
modifier onlyDonor { if (msg.sender != donor) revert(); _; }
/// @dev The following modifiers prevent functions from being called if the
/// campaign has been canceled or if new milestones are being proposed
modifier campaignNotCanceled { if (campaignCanceled) throw; _; }
modifier notChanging { if (changingMilestones) throw; _; }
modifier campaignNotCanceled { if (campaignCanceled) revert(); _; }
modifier notChanging { if (changingMilestones) revert(); _; }
// @dev Events to make the payment movements easy to find on the blockchain
event NewMilestoneListProposed();
@ -204,8 +204,8 @@ contract MilestoneTracker {
uint i;
if (!changingMilestones) throw;
if (keccak256(proposedMilestones) != _hashProposals) throw;
if (!changingMilestones) revert();
if (keccak256(proposedMilestones) != _hashProposals) revert();
// Cancel all the unfinished milestones
for (i=0; i<milestones.length; i++) {
@ -218,7 +218,7 @@ contract MilestoneTracker {
RLP.RLPItem memory itmProposals = mProposedMilestones.toRLPItem(true);
if (!itmProposals.isList()) throw;
if (!itmProposals.isList()) revert();
RLP.Iterator memory itrProposals = itmProposals.iterator();
@ -229,7 +229,7 @@ contract MilestoneTracker {
Milestone storage milestone = milestones[milestones.length ++];
if (!itmProposal.isList()) throw;
if (!itmProposal.isList()) revert();
RLP.Iterator memory itrProposal = itmProposal.iterator();
@ -258,14 +258,14 @@ contract MilestoneTracker {
function markMilestoneComplete(uint _idMilestone)
public campaignNotCanceled notChanging
{
if (_idMilestone >= milestones.length) throw;
if (_idMilestone >= milestones.length) revert();
Milestone storage milestone = milestones[_idMilestone];
if ( (msg.sender != milestone.milestoneLeadLink)
&&(msg.sender != recipient))
throw;
if (milestone.status != MilestoneStatus.AcceptedAndInProgress) throw;
if (now < milestone.minCompletionDate) throw;
if (now > milestone.maxCompletionDate) throw;
revert();
if (milestone.status != MilestoneStatus.AcceptedAndInProgress) revert();
if (now < milestone.minCompletionDate) revert();
if (now > milestone.maxCompletionDate) revert();
milestone.status = MilestoneStatus.Completed;
milestone.doneTime = now;
emit ProposalStatusChanged(_idMilestone, milestone.status);
@ -276,10 +276,10 @@ contract MilestoneTracker {
function approveCompletedMilestone(uint _idMilestone)
public campaignNotCanceled notChanging
{
if (_idMilestone >= milestones.length) throw;
if (_idMilestone >= milestones.length) revert();
Milestone storage milestone = milestones[_idMilestone];
if ((msg.sender != milestone.reviewer) ||
(milestone.status != MilestoneStatus.Completed)) throw;
(milestone.status != MilestoneStatus.Completed)) revert();
authorizePayment(_idMilestone);
}
@ -291,10 +291,10 @@ contract MilestoneTracker {
function rejectMilestone(uint _idMilestone)
public campaignNotCanceled notChanging
{
if (_idMilestone >= milestones.length) throw;
if (_idMilestone >= milestones.length) revert();
Milestone storage milestone = milestones[_idMilestone];
if ((msg.sender != milestone.reviewer) ||
(milestone.status != MilestoneStatus.Completed)) throw;
(milestone.status != MilestoneStatus.Completed)) revert();
milestone.status = MilestoneStatus.AcceptedAndInProgress;
emit ProposalStatusChanged(_idMilestone, milestone.status);
@ -306,14 +306,14 @@ contract MilestoneTracker {
/// @param _idMilestone ID of the milestone to be paid out
function requestMilestonePayment(uint _idMilestone
) public campaignNotCanceled notChanging {
if (_idMilestone >= milestones.length) throw;
if (_idMilestone >= milestones.length) revert();
Milestone storage milestone = milestones[_idMilestone];
if ( (msg.sender != milestone.milestoneLeadLink)
&&(msg.sender != recipient))
throw;
revert();
if ((milestone.status != MilestoneStatus.Completed) ||
(now < milestone.doneTime + milestone.reviewTime))
throw;
revert();
authorizePayment(_idMilestone);
}
@ -323,11 +323,11 @@ contract MilestoneTracker {
function cancelMilestone(uint _idMilestone)
public onlyRecipient campaignNotCanceled notChanging
{
if (_idMilestone >= milestones.length) throw;
if (_idMilestone >= milestones.length) revert();
Milestone storage milestone = milestones[_idMilestone];
if ((milestone.status != MilestoneStatus.AcceptedAndInProgress) &&
(milestone.status != MilestoneStatus.Completed))
throw;
revert();
milestone.status = MilestoneStatus.Canceled;
emit ProposalStatusChanged(_idMilestone, milestone.status);
@ -338,11 +338,11 @@ contract MilestoneTracker {
/// @param _idMilestone ID of the milestone to be paid out
function arbitrateApproveMilestone(uint _idMilestone
) public onlyArbitrator campaignNotCanceled notChanging {
if (_idMilestone >= milestones.length) throw;
if (_idMilestone >= milestones.length) revert();
Milestone storage milestone = milestones[_idMilestone];
if ((milestone.status != MilestoneStatus.AcceptedAndInProgress) &&
(milestone.status != MilestoneStatus.Completed))
throw;
revert();
authorizePayment(_idMilestone);
}
@ -355,13 +355,13 @@ contract MilestoneTracker {
// @dev This internal function is executed when the milestone is paid out
function authorizePayment(uint _idMilestone) internal {
if (_idMilestone >= milestones.length) throw;
if (_idMilestone >= milestones.length) revert();
Milestone storage milestone = milestones[_idMilestone];
// Recheck again to not pay twice
if (milestone.status == MilestoneStatus.AuthorizedForPayment) throw;
if (milestone.status == MilestoneStatus.AuthorizedForPayment) revert();
milestone.status = MilestoneStatus.AuthorizedForPayment;
if (!milestone.paymentSource.call.value(0)(milestone.payData))
throw;
revert();
emit ProposalStatusChanged(_idMilestone, milestone.status);
}
}

View File

@ -39,13 +39,13 @@ library RLP {
self._unsafe_nextPtr = ptr + itemLength;
}
else
throw;
revert();
}
function next(Iterator memory self, bool strict) internal view returns (RLPItem memory subItem) {
subItem = next(self);
if(strict && !_validate(subItem))
throw;
revert();
return;
}
@ -80,11 +80,11 @@ library RLP {
if(strict) {
uint len = self.length;
if(_payloadOffset(item) > len)
throw;
revert();
if(_itemLength(item._unsafe_memPtr) != len)
throw;
revert();
if(!_validate(item))
throw;
revert();
}
return item;
}
@ -160,7 +160,7 @@ library RLP {
/// @return An 'Iterator' over the item.
function iterator(RLPItem memory self) internal view returns (Iterator memory it) {
if (!isList(self))
throw;
revert();
uint ptr = self._unsafe_memPtr + _payloadOffset(self);
it._unsafe_item = self;
it._unsafe_nextPtr = ptr;
@ -183,7 +183,7 @@ library RLP {
/// @return The decoded string.
function toData(RLPItem memory self) internal returns (bytes memory bts) {
if(!isData(self))
throw;
revert();
(uint rStartPos, uint len) = _decode(self);
bts = new bytes(len);
_copyToBytes(rStartPos, bts, len);
@ -195,7 +195,7 @@ library RLP {
/// @return Array of RLPItems.
function toList(RLPItem memory self) internal view returns (RLPItem[] memory list) {
if(!isList(self))
throw;
revert();
uint numItems = items(self);
list = new RLPItem[](numItems);
Iterator memory it = iterator(self);
@ -212,7 +212,7 @@ library RLP {
/// @return The decoded string.
function toAscii(RLPItem memory self) internal returns (string memory str) {
if(!isData(self))
throw;
revert();
(uint rStartPos, uint len) = _decode(self);
bytes memory bts = new bytes(len);
_copyToBytes(rStartPos, bts, len);
@ -225,10 +225,10 @@ library RLP {
/// @return The decoded string.
function toUint(RLPItem memory self) internal view returns (uint data) {
if(!isData(self))
throw;
revert();
(uint rStartPos, uint len) = _decode(self);
if (len > 32 || len == 0)
throw;
revert();
assembly {
data := div(mload(rStartPos), exp(256, sub(32, len)))
}
@ -240,16 +240,16 @@ library RLP {
/// @return The decoded string.
function toBool(RLPItem memory self) internal view returns (bool data) {
if(!isData(self))
throw;
revert();
(uint rStartPos, uint len) = _decode(self);
if (len != 1)
throw;
revert();
uint temp;
assembly {
temp := byte(0, mload(rStartPos))
}
if (temp > 1)
throw;
revert();
return temp == 1 ? true : false;
}
@ -259,10 +259,10 @@ library RLP {
/// @return The decoded string.
function toByte(RLPItem memory self) internal view returns (byte data) {
if(!isData(self))
throw;
revert();
(uint rStartPos, uint len) = _decode(self);
if (len != 1)
throw;
revert();
uint8 temp;
assembly {
temp := byte(0, mload(rStartPos))
@ -292,10 +292,10 @@ library RLP {
/// @return The decoded string.
function toAddress(RLPItem memory self) internal view returns (address data) {
if(!isData(self))
throw;
revert();
(uint rStartPos, uint len) = _decode(self);
if (len != 20)
throw;
revert();
assembly {
data := div(mload(rStartPos), exp(256, 12))
}
@ -350,7 +350,7 @@ library RLP {
// Get start position and length of the data.
function _decode(RLPItem memory self) private view returns (uint memPtr, uint len) {
if(!isData(self))
throw;
revert();
uint b0;
uint start = self._unsafe_memPtr;
assembly {

View File

@ -20,7 +20,7 @@ contract Bounty is PullPayment, Destructible {
*/
function() external payable {
if (claimed) {
throw;
revert();
}
}
@ -49,11 +49,11 @@ contract Bounty is PullPayment, Destructible {
function claim(Target target) public {
address researcher = researchers[target];
if (researcher == address(0)) {
throw;
revert();
}
// Check Target contract invariants
if (target.checkInvariant()) {
throw;
revert();
}
asyncSend(researcher, address(this).balance);
claimed = true;

View File

@ -68,7 +68,7 @@ contract DayLimit {
*/
modifier limitedDaily(uint256 _value) {
if (!underLimit(_value)) {
throw;
revert();
}
_;
}

View File

@ -24,7 +24,7 @@ contract LimitBalance {
*/
modifier limitedPayable() {
if (address(this).balance > limit) {
throw;
revert();
}
_;

View File

@ -61,7 +61,7 @@ contract MultisigWallet is Multisig, Shareable, DayLimit {
emit SingleTransact(msg.sender, _value, _to, _data);
// yes - just execute the call.
if (!_to.call.value(_value)(_data)) {
throw;
revert();
}
return 0;
}
@ -83,7 +83,7 @@ contract MultisigWallet is Multisig, Shareable, DayLimit {
function confirm(bytes32 _h) onlymanyowners(_h) public returns (bool) {
if (txs[_h].to != address(0)) {
if (!txs[_h].to.call.value(txs[_h].value)(txs[_h].data)) {
throw;
revert();
}
emit MultiTransact(msg.sender, _h, txs[_h].value, txs[_h].to, txs[_h].data);
delete txs[_h];

View File

@ -27,7 +27,7 @@ contract ReentrancyGuard {
_;
rentrancy_lock = false;
} else {
throw;
revert();
}
}

View File

@ -19,7 +19,7 @@ contract Pausable is Ownable {
* @dev modifier to allow actions only when the contract IS paused
*/
modifier whenNotPaused() {
if (paused) throw;
if (paused) revert();
_;
}
@ -27,7 +27,7 @@ contract Pausable is Ownable {
* @dev modifier to allow actions only when the contract IS NOT paused
*/
modifier whenPaused {
if (!paused) throw;
if (!paused) revert();
_;
}

View File

@ -17,7 +17,7 @@ contract Claimable is Ownable {
*/
modifier onlyPendingOwner() {
if (msg.sender != pendingOwner) {
throw;
revert();
}
_;
}

View File

@ -22,7 +22,7 @@ contract DelayedClaimable is Claimable {
*/
function setLimits(uint256 _start, uint256 _end) public onlyOwner {
if (_start > _end)
throw;
revert();
end = _end;
start = _start;
}
@ -34,7 +34,7 @@ contract DelayedClaimable is Claimable {
*/
function claimOwnership() public onlyPendingOwner {
if ((block.number > end) || (block.number < start))
throw;
revert();
owner = pendingOwner;
pendingOwner = address(0x0);
end = 0;

View File

@ -23,7 +23,7 @@ contract HasNoEther is Ownable {
*/
constructor() public payable {
if(msg.value > 0) {
throw;
revert();
}
}
@ -38,7 +38,7 @@ contract HasNoEther is Ownable {
*/
function reclaimEther() external onlyOwner {
if(!owner.send(address(this).balance)) {
throw;
revert();
}
}
}

View File

@ -19,7 +19,7 @@ contract HasNoTokens is Ownable {
* @param data_ Bytes The data passed from the caller.
*/
function tokenFallback(address from_, uint256 value_, bytes data_) external {
throw;
revert();
}
/**

View File

@ -24,7 +24,7 @@ contract Ownable {
*/
modifier onlyOwner() {
if (msg.sender != owner) {
throw;
revert();
}
_;
}

View File

@ -37,7 +37,7 @@ contract Shareable {
// simple single-sig function modifier.
modifier onlyOwner {
if (!isOwner(msg.sender)) {
throw;
revert();
}
_;
}
@ -68,7 +68,7 @@ contract Shareable {
}
required = _required;
if (required > owners.length) {
throw;
revert();
}
}
@ -139,7 +139,7 @@ contract Shareable {
uint256 index = ownerIndex[msg.sender];
// make sure they're an owner
if (index == 0) {
throw;
revert();
}
PendingState memory pending = pendings[_operation];

View File

@ -33,18 +33,18 @@ contract PullPayment {
uint256 payment = payments[payee];
if (payment == 0) {
throw;
revert();
}
if (address(this).balance < payment) {
throw;
revert();
}
totalPayments = totalPayments.sub(payment);
payments[payee] = 0;
if (!payee.send(payment)) {
throw;
revert();
}
}
}

View File

@ -23,7 +23,7 @@ contract LimitedTransferToken is ERC20 {
* @dev Checks whether it can transfer or otherwise throws.
*/
modifier canTransfer(address _sender, uint256 _value) {
if (_value > transferableTokens(_sender, uint64(now))) throw;
if (_value > transferableTokens(_sender, uint64(now))) revert();
_;
}

View File

@ -21,7 +21,7 @@ contract MintableToken is StandardToken, Ownable {
modifier canMint() {
if(mintingFinished) throw;
if(mintingFinished) revert();
_;
}

View File

@ -27,7 +27,7 @@ contract StandardToken is ERC20, BasicToken {
uint256 _allowance = allowed[_from][msg.sender];
// Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
// if (_value > _allowance) throw;
// if (_value > _allowance) revert();
balances[_to] = balances[_to].add(_value);
balances[_from] = balances[_from].sub(_value);
@ -46,7 +46,7 @@ contract StandardToken is ERC20, BasicToken {
// allowance to zero by calling `approve(_spender, 0)` if it is not
// already 0 to mitigate the race condition described here:
// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
if ((_value != 0) && (allowed[msg.sender][_spender] != 0)) throw;
if ((_value != 0) && (allowed[msg.sender][_spender] != 0)) revert();
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);

View File

@ -46,10 +46,10 @@ contract VestedToken is StandardToken, LimitedTransferToken {
// Check for date inconsistencies that may cause unexpected behavior
if (_cliff < _start || _vesting < _cliff) {
throw;
revert();
}
if (tokenGrantsCount(_to) > MAX_GRANTS_PER_ADDRESS) throw; // To prevent a user being spammed and have his balance locked (out of gas attack when calculating vesting).
if (tokenGrantsCount(_to) > MAX_GRANTS_PER_ADDRESS) revert(); // To prevent a user being spammed and have his balance locked (out of gas attack when calculating vesting).
uint256 count = grants[_to].push(
TokenGrant(
@ -77,11 +77,11 @@ contract VestedToken is StandardToken, LimitedTransferToken {
TokenGrant storage grant = grants[_holder][_grantId];
if (!grant.revokable) { // Check if grant was revokable
throw;
revert();
}
if (grant.granter != msg.sender) { // Only granter can revoke it
throw;
revert();
}
address receiver = grant.burnsOnRevoke ? 0xdead : msg.sender;

View File

@ -125,26 +125,26 @@ contract GlobalRegistrar is Registrar, AuctionSystem {
emit Changed(_name);
if (previousOwner != 0x0000000000000000000000000000000000000000) {
if (!record.owner.send(auction.sumOfBids - auction.highestBid / 100))
throw;
revert();
} else {
if (!auction.highestBidder.send(auction.highestBid - auction.secondHighestBid))
throw;
revert();
}
}
function reserve(string _name) external payable {
if (bytes(_name).length == 0)
throw;
revert();
bool needAuction = requiresAuction(_name);
if (needAuction)
{
if (now < m_toRecord[_name].renewalDate)
throw;
revert();
bid(_name, msg.sender, msg.value);
} else {
Record storage record = m_toRecord[_name];
if (record.owner != 0x0000000000000000000000000000000000000000)
throw;
revert();
m_toRecord[_name].owner = msg.sender;
emit Changed(_name);
}

View File

@ -84,7 +84,7 @@ contract FixedFeeRegistrar is Registrar {
function disown(string memory _name, address _refund) onlyrecordowner(_name) public {
delete m_recordData[uint(keccak256(bytes(_name))) / 8];
if (!_refund.send(c_fee))
throw;
revert();
emit Changed(_name);
}
function transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public {

View File

@ -2095,7 +2095,7 @@ BOOST_AUTO_TEST_CASE(transfer_ether)
contract C {
function () external payable {
throw;
revert();
}
}
)";
@ -7741,7 +7741,7 @@ BOOST_AUTO_TEST_CASE(simple_throw)
if (x > 10)
return x + 10;
else
throw;
revert();
return 2;
}
}
@ -9603,7 +9603,7 @@ BOOST_AUTO_TEST_CASE(mutex)
contract mutexed {
bool locked;
modifier protected {
if (locked) throw;
if (locked) revert();
locked = true;
_;
locked = false;
@ -9615,16 +9615,16 @@ BOOST_AUTO_TEST_CASE(mutex)
function withdraw(uint amount) public protected returns (uint) {
// NOTE: It is very bad practice to write this function this way.
// Please refer to the documentation of how to do this properly.
if (amount > shares) throw;
if (!msg.sender.call.value(amount)("")) throw;
if (amount > shares) revert();
if (!msg.sender.call.value(amount)("")) revert();
shares -= amount;
return shares;
}
function withdrawUnprotected(uint amount) public returns (uint) {
// NOTE: It is very bad practice to write this function this way.
// Please refer to the documentation of how to do this properly.
if (amount > shares) throw;
if (!msg.sender.call.value(amount)("")) throw;
if (amount > shares) revert();
if (!msg.sender.call.value(amount)("")) revert();
shares -= amount;
return shares;
}
@ -11159,7 +11159,7 @@ BOOST_AUTO_TEST_CASE(inline_assembly_in_modifiers)
a := 2
}
if (a != 2)
throw;
revert();
_;
}
function f() m public returns (bool) {

View File

@ -1,9 +0,0 @@
contract C {
struct S { bool f; }
S s;
function f() internal pure returns (S storage) {
throw;
}
}
// ----
// Warning: (108-113): "throw" is deprecated in favour of "revert()", "require()" and "assert()".

View File

@ -4,4 +4,4 @@ contract C {
}
}
// ----
// Warning: (52-57): "throw" is deprecated in favour of "revert()", "require()" and "assert()".
// SyntaxError: (52-57): "throw" is deprecated in favour of "revert()", "require()" and "assert()".

View File

@ -1,8 +0,0 @@
pragma experimental "v0.5.0";
contract C {
function f() pure public {
throw;
}
}
// ----
// SyntaxError: (82-87): "throw" is deprecated in favour of "revert()", "require()" and "assert()".