diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-01-07 06:00:46 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-01-07 06:00:46 +0000 |
commit | 02db2fa1a919655cb54a160131c3ca6a3fa215b5 (patch) | |
tree | 739cca0952f0b9344e93b1bc928cf57f2b900d39 /lib/Sema/SemaDecl.cpp | |
parent | 1a1eb1e55e1bccc461ae696bc445541f6fef3cd0 (diff) | |
download | clang-02db2fa1a919655cb54a160131c3ca6a3fa215b5.tar.gz |
DR674, PR38883, PR40238: Qualified friend lookup should look for a
template specialization if there is no matching non-template function.
This exposed a couple of related bugs:
- we would sometimes substitute into a friend template instead of a
suitable non-friend declaration; this would now crash because we'd
decide the specialization of the friend is a redeclaration of itself
- ADL failed to properly handle the case where an invisible local
extern declaration redeclares an invisible friend
Both are fixed herein: in particular, we now never make invisible
friends or local extern declarations visible to name lookup unless
they are the only declaration of the entity. (We already mostly did
this for local extern declarations.)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350505 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 17 |
1 files changed, 6 insertions, 11 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 40b0ed3779..f607873a73 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5518,15 +5518,8 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, // If this has an identifier and is not a function template specialization, // add it to the scope stack. - if (New->getDeclName() && AddToScope) { - // Only make a locally-scoped extern declaration visible if it is the first - // declaration of this entity. Qualified lookup for such an entity should - // only find this declaration if there is no visible declaration of it. - bool AddToContext = !D.isRedeclaration() || !New->isLocalExternDecl(); - PushOnScopeChains(New, S, AddToContext); - if (!AddToContext) - CurContext->addHiddenDecl(New); - } + if (New->getDeclName() && AddToScope) + PushOnScopeChains(New, S); if (isInOpenMPDeclareTargetContext()) checkDeclIsAllowedInOpenMPTarget(nullptr, New); @@ -7728,8 +7721,10 @@ static NamedDecl *DiagnoseInvalidRedeclaration( SmallVector<std::pair<FunctionDecl *, unsigned>, 1> NearMatches; TypoCorrection Correction; bool IsDefinition = ExtraArgs.D.isFunctionDefinition(); - unsigned DiagMsg = IsLocalFriend ? diag::err_no_matching_local_friend - : diag::err_member_decl_does_not_match; + unsigned DiagMsg = + IsLocalFriend ? diag::err_no_matching_local_friend : + NewFD->getFriendObjectKind() ? diag::err_qualified_friend_no_match : + diag::err_member_decl_does_not_match; LookupResult Prev(SemaRef, Name, NewFD->getLocation(), IsLocalFriend ? Sema::LookupLocalFriendName : Sema::LookupOrdinaryName, |