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