diff options
author | chriseth <chris@ethereum.org> | 2017-01-13 20:05:02 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-13 20:05:02 +0800 |
commit | 60cc1668517f56ce6ca8225555472e7a27eab8b0 (patch) | |
tree | 8eac35131efc4beeee921356052375233edd7102 /libsolidity/analysis | |
parent | 822622cf5bf23e79a6e2292cb837d1a39ca1c419 (diff) | |
parent | e22672b7c739dde9f37a919e63245abda4b1fc89 (diff) | |
download | dexon-solidity-60cc1668517f56ce6ca8225555472e7a27eab8b0.tar dexon-solidity-60cc1668517f56ce6ca8225555472e7a27eab8b0.tar.gz dexon-solidity-60cc1668517f56ce6ca8225555472e7a27eab8b0.tar.bz2 dexon-solidity-60cc1668517f56ce6ca8225555472e7a27eab8b0.tar.lz dexon-solidity-60cc1668517f56ce6ca8225555472e7a27eab8b0.tar.xz dexon-solidity-60cc1668517f56ce6ca8225555472e7a27eab8b0.tar.zst dexon-solidity-60cc1668517f56ce6ca8225555472e7a27eab8b0.zip |
Merge pull request #1561 from ethereum/develop
Merge develop into release for 0.4.8
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r-- | libsolidity/analysis/DeclarationContainer.cpp | 13 | ||||
-rw-r--r-- | libsolidity/analysis/NameAndTypeResolver.cpp | 54 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 19 |
3 files changed, 75 insertions, 11 deletions
diff --git a/libsolidity/analysis/DeclarationContainer.cpp b/libsolidity/analysis/DeclarationContainer.cpp index 1599b83a..f8c12c5b 100644 --- a/libsolidity/analysis/DeclarationContainer.cpp +++ b/libsolidity/analysis/DeclarationContainer.cpp @@ -44,10 +44,19 @@ Declaration const* DeclarationContainer::conflictingDeclaration( if (dynamic_cast<FunctionDefinition const*>(&_declaration)) { - // check that all other declarations with the same name are functions + // check that all other declarations with the same name are functions or a public state variable for (Declaration const* declaration: declarations) - if (!dynamic_cast<FunctionDefinition const*>(declaration)) + { + if (dynamic_cast<FunctionDefinition const*>(declaration)) + continue; + if (auto variableDeclaration = dynamic_cast<VariableDeclaration const*>(declaration)) + { + if (variableDeclaration->isStateVariable() && !variableDeclaration->isConstant() && variableDeclaration->isPublic()) + continue; return declaration; + } + return declaration; + } } else if (declarations.size() == 1 && declarations.front() == &_declaration) return nullptr; diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 2a33a501..08323243 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -260,10 +260,16 @@ vector<Declaration const*> NameAndTypeResolver::cleanedDeclarations( for (auto it = _declarations.begin(); it != _declarations.end(); ++it) { solAssert(*it, ""); - // the declaration is functionDefinition while declarations > 1 - FunctionDefinition const& functionDefinition = dynamic_cast<FunctionDefinition const&>(**it); - FunctionType functionType(functionDefinition); - for (auto parameter: functionType.parameterTypes() + functionType.returnParameterTypes()) + // the declaration is functionDefinition or a VariableDeclaration while declarations > 1 + solAssert(dynamic_cast<FunctionDefinition const*>(*it) || dynamic_cast<VariableDeclaration const*>(*it), + "Found overloading involving something not a function or a variable"); + + shared_ptr<FunctionType const> functionType { (*it)->functionType(false) }; + if (!functionType) + functionType = (*it)->functionType(true); + solAssert(functionType, "failed to determine the function type of the overloaded"); + + for (auto parameter: functionType->parameterTypes() + functionType->returnParameterTypes()) if (!parameter) reportFatalDeclarationError(_identifier.location(), "Function type can not be used in this context"); @@ -272,8 +278,10 @@ vector<Declaration const*> NameAndTypeResolver::cleanedDeclarations( uniqueFunctions.end(), [&](Declaration const* d) { - FunctionType newFunctionType(dynamic_cast<FunctionDefinition const&>(*d)); - return functionType.hasEqualArgumentTypes(newFunctionType); + shared_ptr<FunctionType const> newFunctionType { d->functionType(false) }; + if (!newFunctionType) + newFunctionType = d->functionType(true); + return newFunctionType && functionType->hasEqualArgumentTypes(*newFunctionType); } )) uniqueFunctions.push_back(*it); @@ -289,7 +297,39 @@ void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base) for (auto const& declaration: nameAndDeclaration.second) // Import if it was declared in the base, is not the constructor and is visible in derived classes if (declaration->scope() == &_base && declaration->isVisibleInDerivedContracts()) - m_currentScope->registerDeclaration(*declaration); + if (!m_currentScope->registerDeclaration(*declaration)) + { + SourceLocation firstDeclarationLocation; + SourceLocation secondDeclarationLocation; + Declaration const* conflictingDeclaration = m_currentScope->conflictingDeclaration(*declaration); + solAssert(conflictingDeclaration, ""); + + // Usual shadowing is not an error + if (dynamic_cast<VariableDeclaration const*>(declaration) && dynamic_cast<VariableDeclaration const*>(conflictingDeclaration)) + continue; + + // Usual shadowing is not an error + if (dynamic_cast<ModifierDefinition const*>(declaration) && dynamic_cast<ModifierDefinition const*>(conflictingDeclaration)) + continue; + + if (declaration->location().start < conflictingDeclaration->location().start) + { + firstDeclarationLocation = declaration->location(); + secondDeclarationLocation = conflictingDeclaration->location(); + } + else + { + firstDeclarationLocation = conflictingDeclaration->location(); + secondDeclarationLocation = declaration->location(); + } + + reportDeclarationError( + secondDeclarationLocation, + "Identifier already declared.", + firstDeclarationLocation, + "The previous declaration is here:" + ); + } } void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index e414e27c..67c8ac17 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1500,8 +1500,23 @@ bool TypeChecker::visit(Identifier const& _identifier) if (!annotation.referencedDeclaration) { if (!annotation.argumentTypes) - fatalTypeError(_identifier.location(), "Unable to determine overloaded type."); - if (annotation.overloadedDeclarations.empty()) + { + // The identifier should be a public state variable shadowing other functions + vector<Declaration const*> candidates; + + for (Declaration const* declaration: annotation.overloadedDeclarations) + { + if (VariableDeclaration const* variableDeclaration = dynamic_cast<decltype(variableDeclaration)>(declaration)) + candidates.push_back(declaration); + } + if (candidates.empty()) + fatalTypeError(_identifier.location(), "No matching declaration found after variable lookup."); + else if (candidates.size() == 1) + annotation.referencedDeclaration = candidates.front(); + else + fatalTypeError(_identifier.location(), "No unique declaration found after variable lookup."); + } + else if (annotation.overloadedDeclarations.empty()) fatalTypeError(_identifier.location(), "No candidates for overload resolution found."); else if (annotation.overloadedDeclarations.size() == 1) annotation.referencedDeclaration = *annotation.overloadedDeclarations.begin(); |