r178698 - Complain about attempts to befriend declarations via a using

John McCall rjmccall at apple.com
Wed Apr 3 14:19:48 PDT 2013


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}}
+  };
+}





More information about the cfe-commits mailing list