Skip to content

Conversation

@chase1745
Copy link
Contributor

@chase1745 chase1745 commented Apr 28, 2018

Fixes #3402

Only warns if the contract is a library, but can be changed to all contracts if needed.
Throws Type Error for 0.5.0.

if (_variable.isCallableParameter())
typeLoc = DataLocation::Memory;
if (_variable.isCallableParameter()) {
typeLoc = DataLocation::Memory;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please indent using tabs only.
Please put { on a line of its own.

Coding style: https://github.com/ethereum/solidity/blob/develop/CODING_STYLE.md

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My apologies on this! Should be fixed now.

function f() private pure returns(uint[]) {}
}
// ----
// Warning: (50-56): Parameter is declared as memory. Use an explicit "memory" keyword to silence this warning. No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a test that shows that this warning can actually be removed by adding memory.

Please also add testst for external and internal functions and functions using storage parameters, both in contracts and in libraries.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added these tests for all types of function visibility as well as for contracts and libraries. I also added tests showing the warning is removed by adding a storage location.

auto const& contract = dynamic_cast<ContractDefinition const&>(
*dynamic_cast<Declaration const&>(*_variable.scope()).scope()
);
if (contract.isLibrary()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should this be restricted to libraries only?

Note that for external functions, we have a default data location of calldata which is not possible to express in source code, so we cannot warn about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the original issue you mentioned "We should do the same at least for the case where the contract is a library.", so I only warned for libraries, but I have changed it to warn for contracts as well.

@chase1745
Copy link
Contributor Author

I believe the only issue left is with events. It is warning for no default data location for event parameters, which isn't correct since they are not allowed.
Is there a way to check if the parameter is in an event? @chriseth

@chriseth
Copy link
Contributor

Please add a function isEventParameter in VariableDeclaration similar to isReturnParameter(). It should be enough to dynamic_cast the scope() to EventDeclaration.

if (varLoc == Location::Default)
{
// Warn users (error in 0.5.0) for using default data location in (return) parameters.
if (_variable.sourceUnit().annotation().experimentalFeatures.count(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please create a bool const v050 variable that holds this condition at the beginning of the function.

);
if (varLoc == Location::Default || !contract.isLibrary())
{
if (varLoc == Location::Default)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have to be inside the other condition in line 352?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, because of the or condition, a parameter using memory in a public function would be passed to this if statement, so we need to check if it's using the default location. This is a little confusing, but I didn't want to refactor too much of the existing code.

using Location = VariableDeclaration::Location;
Location varLoc = _variable.referenceLocation();
DataLocation typeLoc = DataLocation::Memory;
const bool v050 = bool(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for an explicit typecast here. Also usually we write this as bool const v050.

{
if (varLoc == Location::Default && !_variable.isEventParameter())
{
// Warn users (error in 0.5.0) for using default data location in (return) parameters.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this comment.

else
m_errorReporter.warning(
_variable.location(),
"Parameter is declared as memory. "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please enclose memory in quotes. Perhaps reword it as Parameter location is assumed as "memory".

else
m_errorReporter.warning(
_variable.location(),
"Parameter is declared as memory. "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same comments apply to this block as to the above block.


bool VariableDeclaration::isEventParameter() const
{
return (bool)dynamic_cast<EventDefinition const*>(scope());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use != nullptr instead of the typecasting.

@axic
Copy link
Contributor

axic commented May 17, 2018

Please add a change log entry, rebase and squash some of the commits (which belong together, i.e. the test changes).

@chase1745
Copy link
Contributor Author

chase1745 commented May 21, 2018

Just pushed a squashed version of commits.
Where should this go in the change log since 0.4.24 was just released? 0.5.0?

@chase1745 chase1745 force-pushed the no-default-loc-params branch from 801b941 to 36f9b1e Compare May 21, 2018 05:53
@chriseth
Copy link
Contributor

@chase1745 yes, please put this inside the 0.5.0 section.

@chase1745 chase1745 force-pushed the no-default-loc-params branch 2 times, most recently from fc94f0a to 9d9a9a3 Compare June 6, 2018 04:28
@chase1745
Copy link
Contributor Author

Added entry to changelog.

@axic
Copy link
Contributor

axic commented Jun 12, 2018

@chase1745 sorry for not responding earlier. This is failing test, mostly in syntaxTests, which means you need to isoltest to regenerate the expectations (since you've added the warning).

"for parameters in publicly visible functions."
);
else
m_errorReporter.warning(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is listed as a breaking change, there is no need to have the non-0.5.0 mode here.

"\"memory\" or \"storage\" for parameters."
);
else
m_errorReporter.warning(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

@axic axic changed the title Warn if function parameter (return) uses default data location. [BREAKING] Warn if function parameter (return) uses default data location. Jun 12, 2018
@chase1745 chase1745 force-pushed the no-default-loc-params branch 2 times, most recently from 91c9c1e to b91c11b Compare June 15, 2018 05:02
@chase1745
Copy link
Contributor Author

I removed checking for non 0.5.0 mode since this is now a breaking change. I also fixed the new tests to represent this and fixed other non-related tests to not use default data location so they could run as intended without receiving this new error. All isoltests are passing for me now.

@chase1745
Copy link
Contributor Author

Quite a few non-syntax tests are failing now since its a pretty big change. I'll be going through and fixing what I can find over the weekend.

@chase1745
Copy link
Contributor Author

Still working on them, there's a good number of failures because of this. There also seems to be quite a few external tests throwing errors because of this, not sure what to do about those?

@axic
Copy link
Contributor

axic commented Jun 19, 2018

@chase1745 regarding the external tests:

@chase1745 chase1745 changed the title [BREAKING] Warn if function parameter (return) uses default data location. [BREAKING] Throw error if function parameters (return) use default data location. Jun 21, 2018
@chase1745
Copy link
Contributor Author

@bit-shift thanks, yeah must've just missed that one in my OpenZeppelin PR, I'll fix that.

@chase1745 chase1745 force-pushed the no-default-loc-params branch from 84eee29 to b2300ac Compare July 8, 2018 22:51
@chase1745 chase1745 force-pushed the no-default-loc-params branch from b2300ac to 0c25155 Compare July 8, 2018 23:22
@chase1745 chase1745 force-pushed the no-default-loc-params branch from 0c25155 to 3cb1bc1 Compare July 8, 2018 23:34
@chase1745
Copy link
Contributor Author

I rebased from develop and also moved tests to more appropriate locations. All tests should be passing once axic/openzeppelin-solidity#8 is merged.

using Location = VariableDeclaration::Location;
Location varLoc = _variable.referenceLocation();
DataLocation typeLoc = DataLocation::Memory;
bool const v050 = _variable.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The next release will be version 0.5.0, so there's no need [anymore] to optionally check for this, is it?

Copy link
Collaborator

@erak erak Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, since this is a breaking change, the warning should be turned into an error (and therefor this check can be removed.)

Copy link
Collaborator

@erak erak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the check for pragma experimental "v0.5.0" and turn the warning into an error in ReferencesResolver::endVisit()

@leonardoalt leonardoalt mentioned this pull request Jul 9, 2018
29 tasks
@chase1745
Copy link
Contributor Author

chase1745 commented Jul 9, 2018

@bit-shift That is the the error for local variables, not related to this PR, so I didn’t change it, thought it may be better in a separate PR. Happy to change it though if you all think it’s fine for this PR.

@erak
Copy link
Collaborator

erak commented Jul 9, 2018

@chase1745 Ah yeah, right :) Let's do this in another PR. This one is already pretty large.

@chase1745
Copy link
Contributor Author

@bit-shift Sounds good, I’ll try to submit one this afternoon. Can you re-trigger the tests now that @axic merged in the changes to OpenZeppelin?

@erak
Copy link
Collaborator

erak commented Jul 9, 2018

@chase1745 The external test is still failing (SignatureBouncer.sol). Here's you can run them locally:

  1. Download soljson.js, built on Circle in the build_emscripten step: https://21670-40892817-gh.circle-artifacts.com/0/soljson.js
  2. Place the file under [your build directory]/libsolc/soljson.js
  3. Run test/externalTests.sh [your build directory]/libsolc/soljson.js in the root of Solidity

Doing this will help to find breaking contracts :)

@chase1745
Copy link
Contributor Author

🙄I'll find them all this time! Thanks for the tip!

@chase1745
Copy link
Contributor Author

chase1745 commented Jul 10, 2018

@bit-shift I found 2 parameters in that file to fix, and am almost positive that is all of them in OpenZeppelin, but running the tests the way you said, the current solidity-050 branch passes all tests before adding in these changes. Any ideas why? I want to make sure I get all of them this time.

@chriseth
Copy link
Contributor

Sorry, this needs to be rebased now. Perhaps it would make sense to split this PR into multiple PRs:

  • one that updates the syntax tests
  • one that updates the end to end tests
  • one that updates the external tests
  • one that enforces the logic

@chase1745
Copy link
Contributor Author

@chriseth Yeah that makes sense I think. I'll work on that and submit some PR's.

@chase1745
Copy link
Contributor Author

@chriseth Submitted PR's for syntax tests (merged), external tests (#4512), and end to end tests (#4489). Once all 3 have been merged I'll submit a PR for the actual logic so it passes tests and I don't have to rebase a bunch of times.

@vs77bb
Copy link

vs77bb commented Jul 20, 2018

@chase1745 Great work here. We're happy to tip for all the extra effort you put in - excited to pay out soon 👍

@axic
Copy link
Contributor

axic commented Jul 24, 2018

@chase1745 can this PR be closed? I think #4518 is the last in the row superseding this one.

@chase1745 chase1745 closed this Jul 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants