My mistake, the patch actually does seem to catch this. So I'm going to leave it be...
On Wed, Apr 3, 2013 at 6:18 PM, Stephen Lin <[email protected]> wrote: > Hmm, just realized this actually doesn't address attempts to befriend > functions via using declarations with an unqualified name lookup. > > namespace A { > namespace B { > void C(); > } > using B::C; > > class D { > friend void C(); > private: > ~D() { } > }; > } > > gcc and icc reject the above, clang (before and after this patch) > accepts it but I can't quite figure out what it's accepting it > as...B::C() doesn't seem to be friended, but there also doesn't seem > to be a new A::C() declared or ::C() declared either. > > I don't really know if this code is supposed to be legal or not, > actually: the illegality of the qualified name case seems to rest on > this quote, which only applies to the qualified name case: > > "When the declarator-id is qualified, the declaration shall refer > to a previously declared member of the class or namespace to which the > qualifier refers ... the member shall not merely have been introduced > by a using-declaration in the scope of the class or namespace > nominated by the nested-name-specifier of the declarator-id." > > So I could either resolve this by allowing `friend void C();` to > friend `B::C()` above or disallow it like gcc and icc do... > > I guess just go with the latter since this is so minor? Anyone have > any thoughts? > > Stephen > > On Wed, Apr 3, 2013 at 5:19 PM, John McCall <[email protected]> wrote: >> Author: rjmccall >> Date: Wed Apr 3 16:19:47 2013 >> New Revision: 178698 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=178698&view=rev >> Log: >> Complain about attempts to befriend declarations via a using >> declaration. Patch by Stephen Lin! >> >> Modified: >> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> cfe/trunk/lib/Sema/SemaDecl.cpp >> cfe/trunk/lib/Sema/SemaOverload.cpp >> cfe/trunk/test/SemaCXX/friend.cpp >> >> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=178698&r1=178697&r2=178698&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) >> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Apr 3 16:19:47 >> 2013 >> @@ -867,6 +867,8 @@ def err_friend_def_in_local_class : Erro >> "friend function cannot be defined in a local class">; >> def err_friend_not_first_in_declaration : Error< >> "'friend' must appear first in a non-function declaration">; >> +def err_using_decl_friend : Error< >> + "cannot befriend target of using declaration">; >> >> def err_invalid_member_in_interface : Error< >> "%select{data member |non-public member function |static member function >> |" >> >> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=178698&r1=178697&r2=178698&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Apr 3 16:19:47 2013 >> @@ -2277,6 +2277,15 @@ bool Sema::MergeFunctionDecl(FunctionDec >> Old = dyn_cast<FunctionDecl>(OldD); >> if (!Old) { >> if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(OldD)) { >> + if (New->getFriendObjectKind()) { >> + Diag(New->getLocation(), diag::err_using_decl_friend); >> + Diag(Shadow->getTargetDecl()->getLocation(), >> + diag::note_using_decl_target); >> + Diag(Shadow->getUsingDecl()->getLocation(), >> + diag::note_using_decl) << 0; >> + return true; >> + } >> + >> Diag(New->getLocation(), diag::err_using_decl_conflict_reverse); >> Diag(Shadow->getTargetDecl()->getLocation(), >> diag::note_using_decl_target); >> >> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=178698&r1=178697&r2=178698&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Wed Apr 3 16:19:47 2013 >> @@ -920,7 +920,8 @@ Sema::CheckOverload(Scope *S, FunctionDe >> // function templates hide function templates with different >> // return types or template parameter lists. >> bool UseMemberUsingDeclRules = >> - (OldIsUsingDecl || NewIsUsingDecl) && CurContext->isRecord(); >> + (OldIsUsingDecl || NewIsUsingDecl) && CurContext->isRecord() && >> + !New->getFriendObjectKind(); >> >> if (FunctionTemplateDecl *OldT = dyn_cast<FunctionTemplateDecl>(OldD)) { >> if (!IsOverload(New, OldT->getTemplatedDecl(), >> UseMemberUsingDeclRules)) { >> >> Modified: cfe/trunk/test/SemaCXX/friend.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/friend.cpp?rev=178698&r1=178697&r2=178698&view=diff >> ============================================================================== >> --- cfe/trunk/test/SemaCXX/friend.cpp (original) >> +++ cfe/trunk/test/SemaCXX/friend.cpp Wed Apr 3 16:19:47 2013 >> @@ -138,3 +138,19 @@ namespace test7 { >> }; >> } >> } >> + >> +// PR15485 >> +namespace test8 { >> + namespace ns1 { >> + namespace ns2 { >> + template<class T> void f(T t); // expected-note {{target of using >> declaration}} >> + } >> + using ns2::f; // expected-note {{using declaration}} >> + } >> + struct A { void f(); }; // expected-note {{target of using declaration}} >> + struct B : public A { using A::f; }; // expected-note {{using >> declaration}} >> + struct X { >> + template<class T> friend void ns1::f(T t); // expected-error {{cannot >> befriend target of using declaration}} >> + friend void B::f(); // expected-error {{cannot befriend target of using >> declaration}} >> + }; >> +} >> >> >> _______________________________________________ >> cfe-commits mailing list >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
