aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--docs/contracts.rst2
-rw-r--r--docs/frequently-asked-questions.rst2
-rw-r--r--docs/types.rst19
-rw-r--r--libsolidity/ast/Types.cpp11
-rw-r--r--libsolidity/ast/Types.h4
-rw-r--r--test/compilationTests/MultiSigWallet/MultiSigWalletFactory.sol2
-rw-r--r--test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimitFactory.sol2
-rw-r--r--test/compilationTests/corion/premium.sol2
-rw-r--r--test/compilationTests/corion/schelling.sol2
-rw-r--r--test/compilationTests/corion/token.sol2
-rw-r--r--test/compilationTests/gnosis/Events/Event.sol2
-rw-r--r--test/compilationTests/gnosis/Markets/Campaign.sol8
-rw-r--r--test/compilationTests/gnosis/Markets/StandardMarket.sol20
-rw-r--r--test/compilationTests/gnosis/Oracles/FutarchyOracle.sol8
-rw-r--r--test/compilationTests/gnosis/Oracles/UltimateOracle.sol4
-rw-r--r--test/compilationTests/zeppelin/Bounty.sol6
-rw-r--r--test/compilationTests/zeppelin/lifecycle/TokenDestructible.sol2
-rw-r--r--test/compilationTests/zeppelin/ownership/HasNoTokens.sol2
-rw-r--r--test/compilationTests/zeppelin/token/TokenTimelock.sol2
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp8
-rw-r--r--test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_inverted.sol4
-rw-r--r--test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol4
-rw-r--r--test/libsolidity/syntaxTests/types/address_to_contract.sol6
-rw-r--r--test/libsolidity/syntaxTests/types/address_to_contract_implicitly.sol7
-rw-r--r--test/libsolidity/syntaxTests/types/contract_to_address.sol7
-rw-r--r--test/libsolidity/syntaxTests/types/contract_to_address_implicitly.sol8
-rw-r--r--test/libsolidity/syntaxTests/types/contract_to_base.sol9
-rw-r--r--test/libsolidity/syntaxTests/types/contract_to_base_base.sol10
-rw-r--r--test/libsolidity/syntaxTests/types/contract_to_derived.sol9
-rw-r--r--test/libsolidity/syntaxTests/types/contract_to_unrelated_contract.sol9
31 files changed, 134 insertions, 50 deletions
diff --git a/Changelog.md b/Changelog.md
index da287000..bcd55955 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -40,6 +40,7 @@ Breaking Changes:
* Type Checker: Disallow arithmetic operations for boolean variables.
* Type Checker: Disallow tight packing of literals. This was already the case in the experimental 0.5.0 mode.
* Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size.
+ * Type Checker: Disallow conversions between unrelated contract types. Explicit conversion via ``address`` can still achieve it.
* Type Checker: Disallow empty tuple components. This was partly already the case in the experimental 0.5.0 mode.
* Type Checker: Disallow multi-variable declarations with mismatching number of values. This was already the case in the experimental 0.5.0 mode.
* Type Checker: Disallow specifying base constructor arguments multiple times in the same inheritance hierarchy. This was already the case in the experimental 0.5.0 mode.
diff --git a/docs/contracts.rst b/docs/contracts.rst
index e78c3ff7..e87c8a67 100644
--- a/docs/contracts.rst
+++ b/docs/contracts.rst
@@ -1,5 +1,7 @@
.. index:: ! contract
+.. _contracts:
+
##########
Contracts
##########
diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst
index cb46dea6..c2df0d3a 100644
--- a/docs/frequently-asked-questions.rst
+++ b/docs/frequently-asked-questions.rst
@@ -379,7 +379,7 @@ In this example::
}
contract A {
- address child;
+ B child;
function test() public {
child = (new B).value(10)(); //construct a new B with 10 wei
diff --git a/docs/types.rst b/docs/types.rst
index d6767b54..566c4c19 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -192,6 +192,23 @@ The ``.gas()`` option is available on all three methods, while the ``.value()``
.. note::
The use of ``callcode`` is discouraged and will be removed in the future.
+Contract Types
+--------------
+
+Every :ref:`contract<contracts>` defines its own type. Contracts can be implicitly converted
+to contracts they inherit from. They can be explicitly converted from and to ``address`` types.
+
+The data representation of a contract is identical to that of the ``address`` type and
+this type is also used in the :ref:`ABI<ABI>`.
+
+Contracts do not support any operators.
+
+The members of contract types are the external functions of the contract including
+public state variables.
+
+.. note::
+ Starting with version 0.5.0 contracts do not derive from the address type, but can still be explicitly converted to address.
+
.. index:: byte array, bytes32
@@ -884,7 +901,7 @@ for each ``_KeyType``, recursively.
function f() public returns (uint) {
MappingExample m = new MappingExample();
m.update(100);
- return m.balances(this);
+ return m.balances(address(this));
}
}
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 2c2d3b68..7b079f45 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -1403,15 +1403,15 @@ bool ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const
{
if (*this == _convertTo)
return true;
- if (_convertTo.category() == Category::Integer)
- return dynamic_cast<IntegerType const&>(_convertTo).isAddress();
if (_convertTo.category() == Category::Contract)
{
auto const& bases = contractDefinition().annotation().linearizedBaseContracts;
if (m_super && bases.size() <= 1)
return false;
- return find(m_super ? ++bases.begin() : bases.begin(), bases.end(),
- &dynamic_cast<ContractType const&>(_convertTo).contractDefinition()) != bases.end();
+ return find(
+ m_super ? ++bases.begin() : bases.begin(), bases.end(),
+ &dynamic_cast<ContractType const&>(_convertTo).contractDefinition()
+ ) != bases.end();
}
return false;
}
@@ -1420,8 +1420,7 @@ bool ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
return
isImplicitlyConvertibleTo(_convertTo) ||
- _convertTo.category() == Category::Integer ||
- _convertTo.category() == Category::Contract;
+ _convertTo == IntegerType(160, IntegerType::Modifier::Address);
}
bool ContractType::isPayable() const
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index 1a676b42..474a6f33 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -692,9 +692,9 @@ public:
virtual Category category() const override { return Category::Contract; }
explicit ContractType(ContractDefinition const& _contract, bool _super = false):
m_contract(_contract), m_super(_super) {}
- /// Contracts can be implicitly converted to super classes and to addresses.
+ /// Contracts can be implicitly converted only to base contracts.
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
- /// Contracts can be converted to themselves and to integers.
+ /// Contracts can only be explicitly converted to address types and base contracts.
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
virtual std::string richIdentifier() const override;
diff --git a/test/compilationTests/MultiSigWallet/MultiSigWalletFactory.sol b/test/compilationTests/MultiSigWallet/MultiSigWalletFactory.sol
index 16219aa2..8d0c1a3f 100644
--- a/test/compilationTests/MultiSigWallet/MultiSigWalletFactory.sol
+++ b/test/compilationTests/MultiSigWallet/MultiSigWalletFactory.sol
@@ -15,7 +15,7 @@ contract MultiSigWalletFactory is Factory {
public
returns (address wallet)
{
- wallet = new MultiSigWallet(_owners, _required);
+ wallet = address(new MultiSigWallet(_owners, _required));
register(wallet);
}
}
diff --git a/test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimitFactory.sol b/test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimitFactory.sol
index e4cfc031..f897d938 100644
--- a/test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimitFactory.sol
+++ b/test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimitFactory.sol
@@ -16,7 +16,7 @@ contract MultiSigWalletWithDailyLimitFactory is Factory {
public
returns (address wallet)
{
- wallet = new MultiSigWalletWithDailyLimit(_owners, _required, _dailyLimit);
+ wallet = address(new MultiSigWalletWithDailyLimit(_owners, _required, _dailyLimit));
register(wallet);
}
}
diff --git a/test/compilationTests/corion/premium.sol b/test/compilationTests/corion/premium.sol
index 45fe7666..31b492f1 100644
--- a/test/compilationTests/corion/premium.sol
+++ b/test/compilationTests/corion/premium.sol
@@ -56,7 +56,7 @@ contract premium is module, safeMath {
require( dbAddress != address(0x00) );
db = ptokenDB(dbAddress);
if ( ! forReplace ) {
- require( db.replaceOwner(this) );
+ require( db.replaceOwner(address(this)) );
isICO = true;
icoAddr = icoContractAddr;
assert( genesisAddr.length == genesisValue.length );
diff --git a/test/compilationTests/corion/schelling.sol b/test/compilationTests/corion/schelling.sol
index 3905e300..bea53680 100644
--- a/test/compilationTests/corion/schelling.sol
+++ b/test/compilationTests/corion/schelling.sol
@@ -259,7 +259,7 @@ contract schelling is module, announcementTypes, schellingVars {
db = schellingDB(_db);
super.registerModuleHandler(_moduleHandler);
if ( ! _forReplace ) {
- require( db.replaceOwner(this) );
+ require( db.replaceOwner(address(this)) );
}
}
function configure(announcementType a, uint256 b) external returns(bool) {
diff --git a/test/compilationTests/corion/token.sol b/test/compilationTests/corion/token.sol
index 6c8f6f24..be6e914b 100644
--- a/test/compilationTests/corion/token.sol
+++ b/test/compilationTests/corion/token.sol
@@ -71,7 +71,7 @@ contract token is safeMath, module, announcementTypes {
exchangeAddress = exchangeContractAddress;
isICO = ! forReplace;
if ( ! forReplace ) {
- require( db.replaceOwner(this) );
+ require( db.replaceOwner(address(this)) );
assert( genesisAddr.length == genesisValue.length );
require( address(this).balance >= genesisAddr.length * 0.2 ether );
for ( uint256 a=0 ; a<genesisAddr.length ; a++ ) {
diff --git a/test/compilationTests/gnosis/Events/Event.sol b/test/compilationTests/gnosis/Events/Event.sol
index 5b1a550c..0a40cf7e 100644
--- a/test/compilationTests/gnosis/Events/Event.sol
+++ b/test/compilationTests/gnosis/Events/Event.sol
@@ -54,7 +54,7 @@ contract Event {
public
{
// Transfer collateral tokens to events contract
- require(collateralToken.transferFrom(msg.sender, this, collateralTokenCount));
+ require(collateralToken.transferFrom(msg.sender, address(this), collateralTokenCount));
// Issue new outcome tokens to sender
for (uint8 i = 0; i < outcomeTokens.length; i++)
outcomeTokens[i].issue(msg.sender, collateralTokenCount);
diff --git a/test/compilationTests/gnosis/Markets/Campaign.sol b/test/compilationTests/gnosis/Markets/Campaign.sol
index f99ede53..119f8df2 100644
--- a/test/compilationTests/gnosis/Markets/Campaign.sol
+++ b/test/compilationTests/gnosis/Markets/Campaign.sol
@@ -102,12 +102,12 @@ contract Campaign {
timedTransitions
atStage(Stages.AuctionStarted)
{
- uint raisedAmount = eventContract.collateralToken().balanceOf(this);
+ uint raisedAmount = eventContract.collateralToken().balanceOf(address(this));
uint maxAmount = funding.sub(raisedAmount);
if (maxAmount < amount)
amount = maxAmount;
// Collect collateral tokens
- require(eventContract.collateralToken().transferFrom(msg.sender, this, amount));
+ require(eventContract.collateralToken().transferFrom(msg.sender, address(this), amount));
contributions[msg.sender] = contributions[msg.sender].add(amount);
if (amount == maxAmount)
stage = Stages.AuctionSuccessful;
@@ -138,7 +138,7 @@ contract Campaign {
returns (Market)
{
market = marketFactory.createMarket(eventContract, marketMaker, fee);
- require(eventContract.collateralToken().approve(market, funding));
+ require(eventContract.collateralToken().approve(address(market), funding));
market.fund(funding);
stage = Stages.MarketCreated;
emit MarketCreation(market);
@@ -156,7 +156,7 @@ contract Campaign {
market.close();
market.withdrawFees();
eventContract.redeemWinnings();
- finalBalance = eventContract.collateralToken().balanceOf(this);
+ finalBalance = eventContract.collateralToken().balanceOf(address(this));
stage = Stages.MarketClosed;
emit MarketClosing();
}
diff --git a/test/compilationTests/gnosis/Markets/StandardMarket.sol b/test/compilationTests/gnosis/Markets/StandardMarket.sol
index 0a9f77db..2f52a896 100644
--- a/test/compilationTests/gnosis/Markets/StandardMarket.sol
+++ b/test/compilationTests/gnosis/Markets/StandardMarket.sol
@@ -60,8 +60,8 @@ contract StandardMarket is Market {
atStage(Stages.MarketCreated)
{
// Request collateral tokens and allow event contract to transfer them to buy all outcomes
- require( eventContract.collateralToken().transferFrom(msg.sender, this, _funding)
- && eventContract.collateralToken().approve(eventContract, _funding));
+ require( eventContract.collateralToken().transferFrom(msg.sender, address(this), _funding)
+ && eventContract.collateralToken().approve(address(eventContract), _funding));
eventContract.buyAllOutcomes(_funding);
funding = _funding;
stage = Stages.MarketFunded;
@@ -76,7 +76,7 @@ contract StandardMarket is Market {
{
uint8 outcomeCount = eventContract.getOutcomeCount();
for (uint8 i = 0; i < outcomeCount; i++)
- require(eventContract.outcomeTokens(i).transfer(creator, eventContract.outcomeTokens(i).balanceOf(this)));
+ require(eventContract.outcomeTokens(i).transfer(creator, eventContract.outcomeTokens(i).balanceOf(address(this))));
stage = Stages.MarketClosed;
emit MarketClosing();
}
@@ -88,7 +88,7 @@ contract StandardMarket is Market {
isCreator
returns (uint fees)
{
- fees = eventContract.collateralToken().balanceOf(this);
+ fees = eventContract.collateralToken().balanceOf(address(this));
// Transfer fees
require(eventContract.collateralToken().transfer(creator, fees));
emit FeeWithdrawal(fees);
@@ -112,8 +112,8 @@ contract StandardMarket is Market {
// Check cost doesn't exceed max cost
require(cost > 0 && cost <= maxCost);
// Transfer tokens to markets contract and buy all outcomes
- require( eventContract.collateralToken().transferFrom(msg.sender, this, cost)
- && eventContract.collateralToken().approve(eventContract, outcomeTokenCost));
+ require( eventContract.collateralToken().transferFrom(msg.sender, address(this), cost)
+ && eventContract.collateralToken().approve(address(eventContract), outcomeTokenCost));
// Buy all outcomes
eventContract.buyAllOutcomes(outcomeTokenCost);
// Transfer outcome tokens to buyer
@@ -142,7 +142,7 @@ contract StandardMarket is Market {
// Check profit is not too low
require(profit > 0 && profit >= minProfit);
// Transfer outcome tokens to markets contract to sell all outcomes
- require(eventContract.outcomeTokens(outcomeTokenIndex).transferFrom(msg.sender, this, outcomeTokenCount));
+ require(eventContract.outcomeTokens(outcomeTokenIndex).transferFrom(msg.sender, address(this), outcomeTokenCount));
// Sell all outcomes
eventContract.sellAllOutcomes(outcomeTokenProfit);
// Transfer profit to seller
@@ -164,11 +164,11 @@ contract StandardMarket is Market {
returns (uint cost)
{
// Buy all outcomes
- require( eventContract.collateralToken().transferFrom(msg.sender, this, outcomeTokenCount)
- && eventContract.collateralToken().approve(eventContract, outcomeTokenCount));
+ require( eventContract.collateralToken().transferFrom(msg.sender, address(this), outcomeTokenCount)
+ && eventContract.collateralToken().approve(address(eventContract), outcomeTokenCount));
eventContract.buyAllOutcomes(outcomeTokenCount);
// Short sell selected outcome
- eventContract.outcomeTokens(outcomeTokenIndex).approve(this, outcomeTokenCount);
+ eventContract.outcomeTokens(outcomeTokenIndex).approve(address(this), outcomeTokenCount);
uint profit = this.sell(outcomeTokenIndex, outcomeTokenCount, minProfit);
cost = outcomeTokenCount - profit;
// Transfer outcome tokens to buyer
diff --git a/test/compilationTests/gnosis/Oracles/FutarchyOracle.sol b/test/compilationTests/gnosis/Oracles/FutarchyOracle.sol
index cf851f5b..83d10b2e 100644
--- a/test/compilationTests/gnosis/Oracles/FutarchyOracle.sol
+++ b/test/compilationTests/gnosis/Oracles/FutarchyOracle.sol
@@ -95,14 +95,14 @@ contract FutarchyOracle is Oracle {
isCreator
{
// Buy all outcomes
- require( categoricalEvent.collateralToken().transferFrom(creator, this, funding)
- && categoricalEvent.collateralToken().approve(categoricalEvent, funding));
+ require( categoricalEvent.collateralToken().transferFrom(creator, address(this), funding)
+ && categoricalEvent.collateralToken().approve(address(categoricalEvent), funding));
categoricalEvent.buyAllOutcomes(funding);
// Fund each market with outcome tokens from categorical event
for (uint8 i = 0; i < markets.length; i++) {
Market market = markets[i];
// Approve funding for market
- require(market.eventContract().collateralToken().approve(market, funding));
+ require(market.eventContract().collateralToken().approve(address(market), funding));
market.fund(funding);
}
emit FutarchyFunding(funding);
@@ -122,7 +122,7 @@ contract FutarchyOracle is Oracle {
market.withdrawFees();
// Redeem collateral token for winning outcome tokens and transfer collateral tokens to creator
categoricalEvent.redeemWinnings();
- require(categoricalEvent.collateralToken().transfer(creator, categoricalEvent.collateralToken().balanceOf(this)));
+ require(categoricalEvent.collateralToken().transfer(creator, categoricalEvent.collateralToken().balanceOf(address(this))));
emit FutarchyClosing();
}
diff --git a/test/compilationTests/gnosis/Oracles/UltimateOracle.sol b/test/compilationTests/gnosis/Oracles/UltimateOracle.sol
index b7cc231c..452a34ec 100644
--- a/test/compilationTests/gnosis/Oracles/UltimateOracle.sol
+++ b/test/compilationTests/gnosis/Oracles/UltimateOracle.sol
@@ -92,7 +92,7 @@ contract UltimateOracle is Oracle {
// There was no challenge yet or the challenge period expired
require( !isChallenged()
&& !isChallengePeriodOver()
- && collateralToken.transferFrom(msg.sender, this, challengeAmount));
+ && collateralToken.transferFrom(msg.sender, address(this), challengeAmount));
outcomeAmounts[msg.sender][_outcome] = challengeAmount;
totalOutcomeAmounts[_outcome] = challengeAmount;
totalAmount = challengeAmount;
@@ -113,7 +113,7 @@ contract UltimateOracle is Oracle {
// Outcome is challenged and front runner period is not over yet and tokens can be transferred
require( isChallenged()
&& !isFrontRunnerPeriodOver()
- && collateralToken.transferFrom(msg.sender, this, amount));
+ && collateralToken.transferFrom(msg.sender, address(this), amount));
outcomeAmounts[msg.sender][_outcome] = outcomeAmounts[msg.sender][_outcome].add(amount);
totalOutcomeAmounts[_outcome] = totalOutcomeAmounts[_outcome].add(amount);
totalAmount = totalAmount.add(amount);
diff --git a/test/compilationTests/zeppelin/Bounty.sol b/test/compilationTests/zeppelin/Bounty.sol
index 55e64071..1b5d05b4 100644
--- a/test/compilationTests/zeppelin/Bounty.sol
+++ b/test/compilationTests/zeppelin/Bounty.sol
@@ -31,8 +31,8 @@ contract Bounty is PullPayment, Destructible {
*/
function createTarget() public returns(Target) {
Target target = Target(deployContract());
- researchers[target] = msg.sender;
- emit TargetCreated(target);
+ researchers[address(target)] = msg.sender;
+ emit TargetCreated(address(target));
return target;
}
@@ -47,7 +47,7 @@ contract Bounty is PullPayment, Destructible {
* @param target contract
*/
function claim(Target target) public {
- address researcher = researchers[target];
+ address researcher = researchers[address(target)];
if (researcher == address(0)) {
revert();
}
diff --git a/test/compilationTests/zeppelin/lifecycle/TokenDestructible.sol b/test/compilationTests/zeppelin/lifecycle/TokenDestructible.sol
index 51f6b68e..c8b773ef 100644
--- a/test/compilationTests/zeppelin/lifecycle/TokenDestructible.sol
+++ b/test/compilationTests/zeppelin/lifecycle/TokenDestructible.sol
@@ -26,7 +26,7 @@ contract TokenDestructible is Ownable {
// Transfer tokens to owner
for(uint256 i = 0; i < tokens.length; i++) {
ERC20Basic token = ERC20Basic(tokens[i]);
- uint256 balance = token.balanceOf(this);
+ uint256 balance = token.balanceOf(address(this));
token.transfer(owner, balance);
}
diff --git a/test/compilationTests/zeppelin/ownership/HasNoTokens.sol b/test/compilationTests/zeppelin/ownership/HasNoTokens.sol
index df4284f1..87e0c6df 100644
--- a/test/compilationTests/zeppelin/ownership/HasNoTokens.sol
+++ b/test/compilationTests/zeppelin/ownership/HasNoTokens.sol
@@ -28,7 +28,7 @@ contract HasNoTokens is Ownable {
*/
function reclaimToken(address tokenAddr) external onlyOwner {
ERC20Basic tokenInst = ERC20Basic(tokenAddr);
- uint256 balance = tokenInst.balanceOf(this);
+ uint256 balance = tokenInst.balanceOf(address(this));
tokenInst.transfer(owner, balance);
}
}
diff --git a/test/compilationTests/zeppelin/token/TokenTimelock.sol b/test/compilationTests/zeppelin/token/TokenTimelock.sol
index fa1af025..a1722ebf 100644
--- a/test/compilationTests/zeppelin/token/TokenTimelock.sol
+++ b/test/compilationTests/zeppelin/token/TokenTimelock.sol
@@ -33,7 +33,7 @@ contract TokenTimelock {
require(msg.sender == beneficiary);
require(now >= releaseTime);
- uint amount = token.balanceOf(this);
+ uint amount = token.balanceOf(address(this));
require(amount > 0);
token.transfer(beneficiary, amount);
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 223250fa..e9e7c93b 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -9420,7 +9420,7 @@ BOOST_AUTO_TEST_CASE(failed_create)
contract C {
uint public x;
constructor() public payable {}
- function f(uint amount) public returns (address) {
+ function f(uint amount) public returns (D) {
x++;
return (new D).value(amount)();
}
@@ -9428,7 +9428,7 @@ BOOST_AUTO_TEST_CASE(failed_create)
if (depth < 1024)
return this.stack(depth - 1);
else
- return f(0);
+ return address(f(0));
}
}
)";
@@ -12524,10 +12524,10 @@ BOOST_AUTO_TEST_CASE(staticcall_for_view_and_pure)
return (new C()).f();
}
function fview() public returns (uint) {
- return (CView(new C())).f();
+ return (CView(address(new C()))).f();
}
function fpure() public returns (uint) {
- return (CPure(new C())).f();
+ return (CPure(address(new C()))).f();
}
}
)";
diff --git a/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_inverted.sol b/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_inverted.sol
index 2a199b3a..17cb701d 100644
--- a/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_inverted.sol
+++ b/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_inverted.sol
@@ -3,11 +3,11 @@
contract B {
A a;
constructor() public {
- a = new A(this);
+ a = new A(address(this));
}
}
contract A {
- constructor(address a) internal {}
+ constructor(address) internal {}
}
// ----
// TypeError: (141-146): Contract with internal constructor cannot be created directly.
diff --git a/test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol b/test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol
index 9f714aea..b66253e4 100644
--- a/test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol
+++ b/test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol
@@ -3,9 +3,9 @@ contract A {
}
}
contract B {
- constructor(address) public {
+ constructor(C) public {
}
- function b(address) public returns (A) {
+ function b(C) public returns (A) {
return new A();
}
}
diff --git a/test/libsolidity/syntaxTests/types/address_to_contract.sol b/test/libsolidity/syntaxTests/types/address_to_contract.sol
new file mode 100644
index 00000000..629a3df0
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/address_to_contract.sol
@@ -0,0 +1,6 @@
+contract C {
+ function f() public pure returns (C c) {
+ c = C(address(2));
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/types/address_to_contract_implicitly.sol b/test/libsolidity/syntaxTests/types/address_to_contract_implicitly.sol
new file mode 100644
index 00000000..efab7c27
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/address_to_contract_implicitly.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public view {
+ C c = address(2);
+ }
+}
+// ----
+// TypeError: (46-62): Type address is not implicitly convertible to expected type contract C.
diff --git a/test/libsolidity/syntaxTests/types/contract_to_address.sol b/test/libsolidity/syntaxTests/types/contract_to_address.sol
new file mode 100644
index 00000000..ec2f8184
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/contract_to_address.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public view {
+ address a = address(this);
+ a;
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/types/contract_to_address_implicitly.sol b/test/libsolidity/syntaxTests/types/contract_to_address_implicitly.sol
new file mode 100644
index 00000000..8be9daac
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/contract_to_address_implicitly.sol
@@ -0,0 +1,8 @@
+contract C {
+ function f() public view {
+ address a = this;
+ a;
+ }
+}
+// ----
+// TypeError: (46-62): Type contract C is not implicitly convertible to expected type address.
diff --git a/test/libsolidity/syntaxTests/types/contract_to_base.sol b/test/libsolidity/syntaxTests/types/contract_to_base.sol
new file mode 100644
index 00000000..b0a24e62
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/contract_to_base.sol
@@ -0,0 +1,9 @@
+contract A {}
+contract B is A {}
+contract C {
+ function f() public {
+ A a = new B();
+ a;
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/types/contract_to_base_base.sol b/test/libsolidity/syntaxTests/types/contract_to_base_base.sol
new file mode 100644
index 00000000..e99e5cdc
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/contract_to_base_base.sol
@@ -0,0 +1,10 @@
+contract A {}
+contract B is A {}
+contract C is B {}
+contract D {
+ function f() public {
+ A a = new C();
+ a;
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/types/contract_to_derived.sol b/test/libsolidity/syntaxTests/types/contract_to_derived.sol
new file mode 100644
index 00000000..ac8df5d1
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/contract_to_derived.sol
@@ -0,0 +1,9 @@
+contract B {}
+contract A is B {}
+contract C {
+ function f() public pure {
+ A a = A(new B());
+ }
+}
+// ----
+// TypeError: (85-95): Explicit type conversion not allowed from "contract B" to "contract A".
diff --git a/test/libsolidity/syntaxTests/types/contract_to_unrelated_contract.sol b/test/libsolidity/syntaxTests/types/contract_to_unrelated_contract.sol
new file mode 100644
index 00000000..b0a4875f
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/contract_to_unrelated_contract.sol
@@ -0,0 +1,9 @@
+contract A {}
+contract B {}
+contract C {
+ function f() public pure {
+ B b = B(new A());
+ }
+}
+// ----
+// TypeError: (80-90): Explicit type conversion not allowed from "contract A" to "contract B".