r178698 - Complain about attempts to befriend declarations via a using
Stephen Lin
swlin at post.harvard.edu
Wed Apr 3 15:23:30 PDT 2013
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 <swlin at post.harvard.edu> 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 <rjmccall at apple.com> 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
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list