{"action":"closed","issue":{"url":"https://api.github.com/repos/ethereum/solidity/issues/373","labels_url":"https://api.github.com/repos/ethereum/solidity/issues/373/labels{/name}","comments_url":"https://api.github.com/repos/ethereum/solidity/issues/373/comments","events_url":"https://api.github.com/repos/ethereum/solidity/issues/373/events","html_url":"https://github.com/ethereum/solidity/issues/373","id":128945058,"number":373,"title":"Solc is compiling contracts that claim code length is 0 on function calls","user":{"login":"jgostylo","id":1153587,"avatar_url":"https://avatars.githubusercontent.com/u/1153587?v=3","gravatar_id":"","url":"https://api.github.com/users/jgostylo","html_url":"https://github.com/jgostylo","followers_url":"https://api.github.com/users/jgostylo/followers","following_url":"https://api.github.com/users/jgostylo/following{/other_user}","gists_url":"https://api.github.com/users/jgostylo/gists{/gist_id}","starred_url":"https://api.github.com/users/jgostylo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jgostylo/subscriptions","organizations_url":"https://api.github.com/users/jgostylo/orgs","repos_url":"https://api.github.com/users/jgostylo/repos","events_url":"https://api.github.com/users/jgostylo/events{/privacy}","received_events_url":"https://api.github.com/users/jgostylo/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2016-01-26T21:18:41Z","updated_at":"2016-01-28T15:50:19Z","closed_at":"2016-01-28T15:50:19Z","body":"Version: 0.2.0-d2f18c73/Release-Darwin/unknown/int linked to libethereum-1.1.1-377f1a37/Release-Darwin/unknown/int\r\n\r\nI am going to apologize for the lack of a small reproducible.  I spent all day trying to reproduce this issue with a smaller subset of my contract and I cannot get it to fail without the full contract.\r\n\r\nThe hub contract is AccountManager and the rest are spoke contracts.  There is a contract \"account_identity\" that is inherited by other contracts.  The only deployed contract is AccountManager:\r\n```\r\n// AccountManager.sol\r\ncontract account_identity {\r\n  address owner;\r\n  address[] admins;\r\n  address[] users;\r\n\r\n  modifier ifUser(){\r\n    bool isUser = false;\r\n    if (msg.sender == owner)\r\n      isUser = true;\r\n    else {\r\n      for (uint i = 0; i < admins.length; i++){\r\n        if (msg.sender == admins[i])\r\n          isUser = true;\r\n          break;\r\n      }\r\n      if (!isUser){\r\n        for (uint j = 0; j < users.length; j++){\r\n          if (msg.sender == users[j])\r\n            isUser = true;\r\n            break;\r\n        }\r\n      }\r\n    }\r\n    if (!isUser)\r\n      throw;\r\n    _\r\n  }\r\n\r\n  modifier ifAdmin(){\r\n    bool isAdmin = false;\r\n    if (msg.sender == owner)\r\n      isAdmin = true;\r\n    else {\r\n      for (uint i = 0; i < admins.length; i++){\r\n        if (msg.sender == admins[i]){\r\n          isAdmin = true;\r\n          break;\r\n        }\r\n      }\r\n    }\r\n    if (!isAdmin)\r\n      throw;\r\n    _\r\n  }\r\n\r\n  modifier ifOwner(){\r\n    if (msg.sender != owner) throw;\r\n    _\r\n  }\r\n\r\n  function addAdmin(address _address) ifAdmin returns(bool success){\r\n    for (uint i = 0; i < admins.length; i++){\r\n      if (admins[i] == _address)\r\n        return false;\r\n    }\r\n    admins.push(_address);\r\n    return true;\r\n  }\r\n\r\n  function removeAdmin(address _address) ifAdmin returns(bool success){\r\n    for (uint i = 0; i < admins.length; i++){\r\n      if (admins[i] == _address){\r\n        delete admins[i];\r\n        return true;\r\n      }\r\n    }\r\n    return false;\r\n  }\r\n\r\n  function isAdmin(address _address) ifAdmin returns(bool success){\r\n    bool isAdmin = false;\r\n\r\n    for (uint i = 0; i < admins.length; i++){\r\n      if (_address == admins[i]){\r\n        isAdmin = true;\r\n        break;\r\n      }\r\n    }\r\n\r\n    return isAdmin;\r\n  }\r\n\r\n  function addUser(address _address) ifAdmin returns(bool success){\r\n    for (uint i = 0; i < users.length; i++){\r\n      if (users[i] == _address)\r\n        return false;\r\n    }\r\n    users.push(_address);\r\n    return true;\r\n  }\r\n\r\n  function removeUser(address _address) ifAdmin returns(bool success){\r\n    for (uint i = 0; i < users.length; i++){\r\n      if (users[i] == _address){\r\n        delete users[i];\r\n        return true;\r\n      }\r\n    }\r\n    return false;\r\n  }\r\n\r\n  function isUser(address _address) ifAdmin returns(bool success){\r\n    bool isUser = false;\r\n\r\n    for (uint i = 0; i < users.length; i++){\r\n      if (_address == users[i]){\r\n        isUser = true;\r\n        break;\r\n      }\r\n    }\r\n\r\n    return isUser;\r\n  }\r\n\r\n  function () {\r\n    throw;\r\n  }\r\n}\r\n\r\ncontract AccountManager is account_identity {\r\n  CompanyCoin companyCoin;\r\n\r\n  struct Customer {\r\n    string name;\r\n    address id;\r\n    bool active;\r\n  }\r\n\r\n  mapping (string => Customer) customers;\r\n\r\n  function AccountManager() {\r\n    owner = msg.sender;\r\n    companyCoin = new CompanyCoin();\r\n  }\r\n\r\n  function createCustomer(string _name, string _companyId, uint _companyCoins) ifUser returns(address id){\r\n    ClientCompany company = new ClientCompany(_name, _companyId, this);\r\n    customers[_companyId] = Customer({\r\n      name: _name,\r\n      id: company,\r\n      active: true\r\n    });\r\n\r\n    companyCoin.mint(company, _companyCoins);\r\n\r\n    return address(company);\r\n  }\r\n\r\n  function removeCustomer(string _companyId) ifUser returns(bool){\r\n    customers[_companyId].active = false;\r\n    return companyCoin.revoke(customers[_companyId].id, 0, true);\r\n  }\r\n\r\n  function getCustomerFunds(string _companyId) ifUser returns(uint funds){\r\n    return companyCoin.balances(customers[_companyId].id);\r\n  }\r\n\r\n  function checkFundsAndPurchase() ifUser returns(bool didPurchase){\r\n    if(companyCoin.balances(msg.sender) > 0){\r\n      companyCoin.revoke(msg.sender, 1, false);\r\n      return true;\r\n    }\r\n    return false;\r\n  }\r\n}\r\n\r\n\r\ncontract CompanyCoin {\r\n  address minter;\r\n  mapping (address => uint) public balances;\r\n\r\n  event Sent(address from, address to, uint amount);\r\n  event Minted(address to, uint amount);\r\n  event Revoked(address from, uint amount);\r\n\r\n  modifier ifMinter(){\r\n    if (msg.sender != minter) throw;\r\n    _\r\n  }\r\n\r\n  function CompanyCoin() {\r\n      minter = msg.sender;\r\n  }\r\n\r\n  function mint(address _address, uint _amount) ifMinter {\r\n      balances[_address] += _amount;\r\n      Minted(_address, _amount);\r\n  }\r\n\r\n  function revoke(address _address, uint _amount, bool _all) ifMinter returns(bool){\r\n    if(_all || _amount > balances[_address]) {\r\n      Revoked(_address, balances[_address]);\r\n      balances[_address] = 0;\r\n      return true;\r\n    }\r\n\r\n    balances[_address] -= _amount;\r\n    Revoked(_address, _amount);\r\n    return true;\r\n  }\r\n\r\n  function send(address receiver, uint amount) {\r\n      if (balances[msg.sender] < amount) return;\r\n      balances[msg.sender] -= amount;\r\n      balances[receiver] += amount;\r\n      Sent(msg.sender, receiver, amount);\r\n  }\r\n\r\n}\r\n\r\n\r\ncontract ClientCompany is account_identity {\r\n  AccountManager accountManager;\r\n  string public companyName;\r\n  string companyId;\r\n\r\n  struct Product {\r\n    string name;\r\n    address id;\r\n    bool active;\r\n    uint companyIdCount;\r\n    mapping(string => bool) companyIdPurchased;\r\n  }\r\n\r\n  Product[] products;\r\n\r\n  function ClientCompany(string _companyName, string _companyId, AccountManager _accountManager) {\r\n    owner = msg.sender;\r\n    accountManager = _accountManager;\r\n    companyName = _companyName;\r\n    companyId = _companyId;\r\n  }\r\n\r\n  function createProduct(string _name) ifOwner returns(address id){\r\n    CompanyProduct c = new CompanyProduct(_name, owner, this);\r\n    products.push(Product(_name, c, true, 0));\r\n  }\r\n\r\n  function checkCompanyId(address _product, string _companyId, bool _shouldAdd) returns(bool isAvailable){\r\n    int foundIndex = -1;\r\n    for (uint i = 0; i < products.length; i++){\r\n      if (products[i].id == _product){\r\n        foundIndex = int(i);\r\n        break;\r\n      }\r\n    }\r\n    if(foundIndex >= 0){\r\n      uint useIndex = uint(foundIndex);\r\n      if (products[useIndex].companyIdPurchased[_companyId])\r\n        return true;\r\n      if (_shouldAdd){\r\n        if(addCompanyId(_companyId, _product))\r\n          return true;\r\n      }\r\n    }\r\n\r\n    return false;\r\n  }\r\n\r\n  function addCompanyId(string _companyId, address _product) returns(bool added){\r\n    if(accountManager.checkFundsAndPurchase()){\r\n      for (uint i = 0; i < products.length; i++){\r\n        if (products[i].id == _product){\r\n          products[i].companyIdPurchased[_companyId] == true;\r\n          return true;\r\n        }\r\n      }\r\n    }\r\n    return false;\r\n  }\r\n\r\n}\r\n\r\ncontract CompanyProduct is account_identity {\r\n  string name;\r\n\r\n  event CompanyIdLookup(string name);\r\n\r\n  function CompanyProduct(string _name, address _owner, address _parent){\r\n    name = _name;\r\n    owner = _owner;\r\n    addAdmin(_parent);\r\n  }\r\n}\r\n```\r\n\r\nAnd the unittest:\r\n```javascript\r\n// test/accountmanager.js\r\ncontract('AccountManager', function(accounts) {\r\n\r\n  var fakeCompany = {'co_name': 'My Fake Company', 'companyId': '001231272', 'companyCoin': 350};\r\n\r\n  it(\"should add and remove my last account as an admin\", function(done){\r\n    var accountContract = AccountManager.deployed();\r\n\r\n    //var addAdmin;\r\n    var checkAdmin;\r\n    var checkRemoved;\r\n\r\n    accountContract.addAdmin(accounts[9]).then(function(success){\r\n      //addAdmin = success;\r\n      //adminLength = length.toNumber();\r\n      return accountContract.isAdmin.call(accounts[9]);\r\n    }).then(function(success){\r\n      checkAdmin = success;\r\n      return accountContract.removeAdmin(accounts[9]);\r\n    }).then(function(success){\r\n      //removeAdmin = success;\r\n      return accountContract.isAdmin.call(accounts[9]);\r\n    }).then(function(success){\r\n      checkRemoved = success;\r\n\r\n      assert.isTrue(checkAdmin, \"Account was not verified as admin\");\r\n      assert.isFalse(checkRemoved, \"Account was not verified as removed from admin\");\r\n\r\n    }).then(done).catch(done);\r\n  });\r\n\r\n\r\n  it(\"should add and remove my second to last account as a user\", function(done){\r\n    var accountContract = AccountManager.deployed();\r\n\r\n    var checkUser;\r\n    var checkRemoved;\r\n\r\n    accountContract.addUser(accounts[8]).then(function(success){\r\n      return accountContract.isUser.call(accounts[8]);\r\n    }).then(function(success){\r\n      checkUser = success;\r\n      return accountContract.removeUser(accounts[8]);\r\n    }).then(function(success){\r\n      return accountContract.isUser.call(accounts[8]);\r\n    }).then(function(success){\r\n      checkRemoved = success;\r\n\r\n      assert.isTrue(checkUser, \"Account was not verified as user\");\r\n      assert.isFalse(checkRemoved, \"Account was not verified as removed from user\");\r\n\r\n    }).then(done).catch(done);\r\n  });\r\n\r\n  it(\"should create a customer and check their funds\", function(done){\r\n    var accountContract = AccountManager.deployed();\r\n\r\n    var customerFunds;\r\n    var customerFundsRevoke;\r\n\r\n    accountContract.createCustomer(fakeCompany.co_name, fakeCompany.companyId, fakeCompany.companyCoin).then(function(tx){\r\n      return accountContract.getCustomerFunds.call(fakeCompany.companyId);\r\n    }).then(function(funds){\r\n      customerFunds = funds.toNumber();\r\n    //   return accountContract.removeCustomer(fakeCompany.companyId);\r\n    // }).then(function(tx){\r\n    //   return accountContract.getCustomerFunds.call(fakeCompany.companyId);\r\n    // }).then(function(funds){\r\n    //   customerFundsRevoke = funds.toNumber();\r\n\r\n      assert.equal(customerFunds, fakeCompany.companyCoin, \"Customer does not have the funds expected\");\r\n      //assert.equal(customerFundsRevoke, 0, \"Customer does not have the empty funds expected\");\r\n\r\n    }).then(done).catch(done);\r\n  });\r\n\r\n});\r\n```\r\n\r\nThis contract compiles but none of the functionality works.  I am using the python testrpc to build/deploy/unit test my contract.  When any calls to my contract are made the EXIT cause is always \"CODE OUT OF RANGE\".  When I debug vm.py from the python ethereum project I see that codelen = len(processed_code) is 0 which is what paths to this error message.\r\n\r\nHere is the problem code as I see it.  In the contract around line 149-156 I am accessing the mapping to the Customer struct and I am accessing two different properties from that struct.\r\n\r\n```\r\n  function removeCustomer(string _companyId) ifUser returns(bool){\r\n    customers[_companyId].active = false;\r\n    return companyCoin.revoke(customers[_companyId].id, 0, true);\r\n  }\r\n\r\n  function getCustomerFunds(string _companyId) ifUser returns(uint funds){\r\n    return companyCoin.balances(customers[_companyId].id);\r\n  }\r\n```\r\n\r\nIf I comment out lines of code that use customers[_companyId] to leave just one active line then the contract works (for everything except what I commented out of course).  I can leave in any one and everything works.  If I have any two of them then nothing works.\r\n\r\nAs I said before I attempted to build up a smaller reproducible and I was not able to get it to fail.  I duplicated this project into another space and started to strip things out and it started to not fail.  I get the feeling that this error is caused by the mapping mixed with the interactivity of the contracts.\r\n\r\nI assume that this issue is a compiler issue because of the behavior.\r\n"}}