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 | 8ce732b46f5570d21f0e92ea783387b2e5a3b846 (patch) | |
tree | 3cf8aefe6223556ba47b2d07890d3bce1301252f /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | 1ac0839098029ce987ce89f0a8c3faf380e50bd1 (diff) | |
download | bcm5719-llvm-8ce732b46f5570d21f0e92ea783387b2e5a3b846.tar.gz bcm5719-llvm-8ce732b46f5570d21f0e92ea783387b2e5a3b846.zip |
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.)
llvm-svn: 350505
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 23 |
1 files changed, 4 insertions, 19 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 2b380bf0dcd..50d01f309bd 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -14414,25 +14414,6 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D, LookupQualifiedName(Previous, DC); - // Ignore things found implicitly in the wrong scope. - // TODO: better diagnostics for this case. Suggesting the right - // qualified scope would be nice... - LookupResult::Filter F = Previous.makeFilter(); - while (F.hasNext()) { - NamedDecl *D = F.next(); - if (!DC->InEnclosingNamespaceSetOf( - D->getDeclContext()->getRedeclContext())) - F.erase(); - } - F.done(); - - if (Previous.empty()) { - D.setInvalidType(); - Diag(Loc, diag::err_qualified_friend_not_found) - << Name << TInfo->getType(); - return nullptr; - } - // C++ [class.friend]p1: A friend of a class is a function or // class that is not a member of the class . . . if (DC->Equals(CurContext)) @@ -14446,6 +14427,10 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D, // A function can be defined in a friend declaration of a class if and // only if the class is a non-local class (9.8), the function name is // unqualified, and the function has namespace scope. + // + // FIXME: We should only do this if the scope specifier names the + // innermost enclosing namespace; otherwise the fixit changes the + // meaning of the code. SemaDiagnosticBuilder DB = Diag(SS.getRange().getBegin(), diag::err_qualified_friend_def); |