diff options
author | chriseth <c@ethdev.com> | 2015-12-01 02:42:39 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-12-01 02:46:26 +0800 |
commit | 7e3bf833ae3810fcd0737f463c20b933029980ca (patch) | |
tree | fdc5e87f454a4093918b172795cb6e3a0a6bfd0a /libsolidity | |
parent | e9c7837c154482a72c8519fbdc9376693ce9a1d5 (diff) | |
download | dexon-solidity-7e3bf833ae3810fcd0737f463c20b933029980ca.tar.gz dexon-solidity-7e3bf833ae3810fcd0737f463c20b933029980ca.tar.zst dexon-solidity-7e3bf833ae3810fcd0737f463c20b933029980ca.zip |
Bugfix for explicit memory types in libraries.
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/ReferencesResolver.cpp | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index 17f93029..2fe53e8b 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -128,19 +128,21 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable) { type = _variable.typeName()->annotation().type; using Location = VariableDeclaration::Location; - Location loc = _variable.referenceLocation(); + Location varLoc = _variable.referenceLocation(); + DataLocation typeLoc = DataLocation::Memory; // References are forced to calldata for external function parameters (not return) // and memory for parameters (also return) of publicly visible functions. // They default to memory for function parameters and storage for local variables. // As an exception, "storage" is allowed for library functions. if (auto ref = dynamic_cast<ReferenceType const*>(type.get())) { + bool isPointer = true; if (_variable.isExternalCallableParameter()) { auto const& contract = dynamic_cast<ContractDefinition const&>(*_variable.scope()->scope()); if (contract.isLibrary()) { - if (loc == Location::Memory) + if (varLoc == Location::Memory) fatalTypeError(_variable.location(), "Location has to be calldata or storage for external " "library functions (remove the \"memory\" keyword)." @@ -149,50 +151,52 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable) else { // force location of external function parameters (not return) to calldata - if (loc != Location::Default) + if (varLoc != Location::Default) fatalTypeError(_variable.location(), "Location has to be calldata for external functions " "(remove the \"memory\" or \"storage\" keyword)." ); } - if (loc == Location::Default) - type = ref->copyForLocation(DataLocation::CallData, true); + if (varLoc == Location::Default) + typeLoc = DataLocation::CallData; + else + typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage; } else if (_variable.isCallableParameter() && _variable.scope()->isPublic()) { auto const& contract = dynamic_cast<ContractDefinition const&>(*_variable.scope()->scope()); // force locations of public or external function (return) parameters to memory - if (loc == Location::Storage && !contract.isLibrary()) + if (varLoc == Location::Storage && !contract.isLibrary()) fatalTypeError(_variable.location(), "Location has to be memory for publicly visible functions " "(remove the \"storage\" keyword)." ); - if (loc == Location::Default || !contract.isLibrary()) - type = ref->copyForLocation(DataLocation::Memory, true); + if (varLoc == Location::Default || !contract.isLibrary()) + typeLoc = DataLocation::Memory; + else + typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage; } else { if (_variable.isConstant()) { - if (loc != Location::Default && loc != Location::Memory) + if (varLoc != Location::Default && varLoc != Location::Memory) fatalTypeError( _variable.location(), "Storage location has to be \"memory\" (or unspecified) for constants." ); - loc = Location::Memory; + typeLoc = DataLocation::Memory; } - if (loc == Location::Default) - loc = _variable.isCallableParameter() ? Location::Memory : Location::Storage; - bool isPointer = !_variable.isStateVariable(); - type = ref->copyForLocation( - loc == Location::Memory ? - DataLocation::Memory : - DataLocation::Storage, - isPointer - ); + else if (varLoc == Location::Default) + typeLoc = _variable.isCallableParameter() ? DataLocation::Memory : DataLocation::Storage; + else + typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage; + isPointer = !_variable.isStateVariable(); } + + type = ref->copyForLocation(typeLoc, isPointer); } - else if (loc != Location::Default && !ref) + else if (varLoc != Location::Default && !ref) fatalTypeError(_variable.location(), "Storage location can only be given for array or struct types."); if (!type) |