@@ -260,10 +260,16 @@ vector<Declaration const*> NameAndTypeResolver::cleanedDeclarations(
260260 for (auto it = _declarations.begin (); it != _declarations.end (); ++it)
261261 {
262262 solAssert (*it, " " );
263- // the declaration is functionDefinition while declarations > 1
264- FunctionDefinition const & functionDefinition = dynamic_cast <FunctionDefinition const &>(**it);
265- FunctionType functionType (functionDefinition);
266- for (auto parameter: functionType.parameterTypes () + functionType.returnParameterTypes ())
263+ // the declaration is functionDefinition or a VariableDeclaration while declarations > 1
264+ solAssert (dynamic_cast <FunctionDefinition const *>(*it) || dynamic_cast <VariableDeclaration const *>(*it),
265+ " Found overloading involving something not a function or a variable" );
266+
267+ shared_ptr<FunctionType const > functionType { (*it)->functionType (false ) };
268+ if (!functionType)
269+ functionType = (*it)->functionType (true );
270+ solAssert (functionType, " failed to determine the function type of the overloaded" );
271+
272+ for (auto parameter: functionType->parameterTypes () + functionType->returnParameterTypes ())
267273 if (!parameter)
268274 reportFatalDeclarationError (_identifier.location (), " Function type can not be used in this context" );
269275
@@ -272,8 +278,10 @@ vector<Declaration const*> NameAndTypeResolver::cleanedDeclarations(
272278 uniqueFunctions.end (),
273279 [&](Declaration const * d)
274280 {
275- FunctionType newFunctionType (dynamic_cast <FunctionDefinition const &>(*d));
276- return functionType.hasEqualArgumentTypes (newFunctionType);
281+ shared_ptr<FunctionType const > newFunctionType { d->functionType (false ) };
282+ if (!newFunctionType)
283+ newFunctionType = d->functionType (true );
284+ return newFunctionType && functionType->hasEqualArgumentTypes (*newFunctionType);
277285 }
278286 ))
279287 uniqueFunctions.push_back (*it);
@@ -289,7 +297,39 @@ void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base)
289297 for (auto const & declaration: nameAndDeclaration.second )
290298 // Import if it was declared in the base, is not the constructor and is visible in derived classes
291299 if (declaration->scope () == &_base && declaration->isVisibleInDerivedContracts ())
292- m_currentScope->registerDeclaration (*declaration);
300+ if (!m_currentScope->registerDeclaration (*declaration))
301+ {
302+ SourceLocation firstDeclarationLocation;
303+ SourceLocation secondDeclarationLocation;
304+ Declaration const * conflictingDeclaration = m_currentScope->conflictingDeclaration (*declaration);
305+ solAssert (conflictingDeclaration, " " );
306+
307+ // Usual shadowing is not an error
308+ if (dynamic_cast <VariableDeclaration const *>(declaration) && dynamic_cast <VariableDeclaration const *>(conflictingDeclaration))
309+ continue ;
310+
311+ // Usual shadowing is not an error
312+ if (dynamic_cast <ModifierDefinition const *>(declaration) && dynamic_cast <ModifierDefinition const *>(conflictingDeclaration))
313+ continue ;
314+
315+ if (declaration->location ().start < conflictingDeclaration->location ().start )
316+ {
317+ firstDeclarationLocation = declaration->location ();
318+ secondDeclarationLocation = conflictingDeclaration->location ();
319+ }
320+ else
321+ {
322+ firstDeclarationLocation = conflictingDeclaration->location ();
323+ secondDeclarationLocation = declaration->location ();
324+ }
325+
326+ reportDeclarationError (
327+ secondDeclarationLocation,
328+ " Identifier already declared." ,
329+ firstDeclarationLocation,
330+ " The previous declaration is here:"
331+ );
332+ }
293333}
294334
295335void NameAndTypeResolver::linearizeBaseContracts (ContractDefinition& _contract)
0 commit comments