@@ -128,19 +128,21 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable)
128128 {
129129 type = _variable.typeName ()->annotation ().type ;
130130 using Location = VariableDeclaration::Location;
131- Location loc = _variable.referenceLocation ();
131+ Location varLoc = _variable.referenceLocation ();
132+ DataLocation typeLoc = DataLocation::Memory;
132133 // References are forced to calldata for external function parameters (not return)
133134 // and memory for parameters (also return) of publicly visible functions.
134135 // They default to memory for function parameters and storage for local variables.
135136 // As an exception, "storage" is allowed for library functions.
136137 if (auto ref = dynamic_cast <ReferenceType const *>(type.get ()))
137138 {
139+ bool isPointer = true ;
138140 if (_variable.isExternalCallableParameter ())
139141 {
140142 auto const & contract = dynamic_cast <ContractDefinition const &>(*_variable.scope ()->scope ());
141143 if (contract.isLibrary ())
142144 {
143- if (loc == Location::Memory)
145+ if (varLoc == Location::Memory)
144146 fatalTypeError (_variable.location (),
145147 " Location has to be calldata or storage for external "
146148 " library functions (remove the \" memory\" keyword)."
@@ -149,50 +151,52 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable)
149151 else
150152 {
151153 // force location of external function parameters (not return) to calldata
152- if (loc != Location::Default)
154+ if (varLoc != Location::Default)
153155 fatalTypeError (_variable.location (),
154156 " Location has to be calldata for external functions "
155157 " (remove the \" memory\" or \" storage\" keyword)."
156158 );
157159 }
158- if (loc == Location::Default)
159- type = ref->copyForLocation (DataLocation::CallData, true );
160+ if (varLoc == Location::Default)
161+ typeLoc = DataLocation::CallData;
162+ else
163+ typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage;
160164 }
161165 else if (_variable.isCallableParameter () && _variable.scope ()->isPublic ())
162166 {
163167 auto const & contract = dynamic_cast <ContractDefinition const &>(*_variable.scope ()->scope ());
164168 // force locations of public or external function (return) parameters to memory
165- if (loc == Location::Storage && !contract.isLibrary ())
169+ if (varLoc == Location::Storage && !contract.isLibrary ())
166170 fatalTypeError (_variable.location (),
167171 " Location has to be memory for publicly visible functions "
168172 " (remove the \" storage\" keyword)."
169173 );
170- if (loc == Location::Default || !contract.isLibrary ())
171- type = ref->copyForLocation (DataLocation::Memory, true );
174+ if (varLoc == Location::Default || !contract.isLibrary ())
175+ typeLoc = DataLocation::Memory;
176+ else
177+ typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage;
172178 }
173179 else
174180 {
175181 if (_variable.isConstant ())
176182 {
177- if (loc != Location::Default && loc != Location::Memory)
183+ if (varLoc != Location::Default && varLoc != Location::Memory)
178184 fatalTypeError (
179185 _variable.location (),
180186 " Storage location has to be \" memory\" (or unspecified) for constants."
181187 );
182- loc = Location ::Memory;
188+ typeLoc = DataLocation ::Memory;
183189 }
184- if (loc == Location::Default)
185- loc = _variable.isCallableParameter () ? Location::Memory : Location::Storage;
186- bool isPointer = !_variable.isStateVariable ();
187- type = ref->copyForLocation (
188- loc == Location::Memory ?
189- DataLocation::Memory :
190- DataLocation::Storage,
191- isPointer
192- );
190+ else if (varLoc == Location::Default)
191+ typeLoc = _variable.isCallableParameter () ? DataLocation::Memory : DataLocation::Storage;
192+ else
193+ typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage;
194+ isPointer = !_variable.isStateVariable ();
193195 }
196+
197+ type = ref->copyForLocation (typeLoc, isPointer);
194198 }
195- else if (loc != Location::Default && !ref)
199+ else if (varLoc != Location::Default && !ref)
196200 fatalTypeError (_variable.location (), " Storage location can only be given for array or struct types." );
197201
198202 if (!type)
0 commit comments