r207682 - Sema: Implement DR477

David Majnemer david.majnemer at gmail.com
Wed Apr 30 11:24:02 PDT 2014


Author: majnemer
Date: Wed Apr 30 13:24:01 2014
New Revision: 207682

URL: http://llvm.org/viewvc/llvm-project?rev=207682&view=rev
Log:
Sema: Implement DR477

Summary: Friend declarations shouldn't mention explicit or virtual.

Reviewers: rsmith

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D3562

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/lib/Sema/DeclSpec.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp
    cfe/trunk/test/CXX/drs/dr4xx.cpp
    cfe/trunk/www/cxx_dr_status.html

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=207682&r1=207681&r2=207682&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Wed Apr 30 13:24:01 2014
@@ -69,7 +69,7 @@ def err_invalid_short_spec : Error<"'sho
 def err_invalid_long_spec : Error<"'long %0' is invalid">;
 def err_invalid_longlong_spec : Error<"'long long %0' is invalid">;
 def err_invalid_complex_spec : Error<"'_Complex %0' is invalid">;
-def err_friend_storage_spec : Error<"'%0' is invalid in friend declarations">;
+def err_friend_decl_spec : Error<"'%0' is invalid in friend declarations">;
 
 def ext_ident_list_in_param : Extension<
   "type-less parameter names in function declaration">;

Modified: cfe/trunk/lib/Sema/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=207682&r1=207681&r2=207682&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Sema/DeclSpec.cpp Wed Apr 30 13:24:01 2014
@@ -1125,14 +1125,41 @@ void DeclSpec::Finish(DiagnosticsEngine
       ThreadHint = FixItHint::CreateRemoval(SCLoc);
     }
 
-    Diag(D, SCLoc, diag::err_friend_storage_spec)
+    Diag(D, SCLoc, diag::err_friend_decl_spec)
       << SpecName << StorageHint << ThreadHint;
 
     ClearStorageClassSpecs();
   }
 
+  // C++11 [dcl.fct.spec]p5:
+  //   The virtual specifier shall be used only in the initial
+  //   declaration of a non-static class member function;
+  // C++11 [dcl.fct.spec]p6:
+  //   The explicit specifier shall be used only in the declaration of
+  //   a constructor or conversion function within its class
+  //   definition;
+  if (isFriendSpecified() && (isVirtualSpecified() || isExplicitSpecified())) {
+    StringRef Keyword;
+    SourceLocation SCLoc;
+
+    if (isVirtualSpecified()) {
+      Keyword = "virtual";
+      SCLoc = getVirtualSpecLoc();
+    } else {
+      Keyword = "explicit";
+      SCLoc = getExplicitSpecLoc();
+    }
+
+    FixItHint Hint = FixItHint::CreateRemoval(SCLoc);
+    Diag(D, SCLoc, diag::err_friend_decl_spec)
+      << Keyword << Hint;
+
+    FS_virtual_specified = FS_explicit_specified = false;
+    FS_virtualLoc = FS_explicitLoc = SourceLocation();
+  }
+
   assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
- 
+
   // Okay, now we can infer the real type.
 
   // TODO: return "auto function" and other bad things based on the real type.

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp?rev=207682&r1=207681&r2=207682&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp Wed Apr 30 13:24:01 2014
@@ -14,3 +14,7 @@ public:
 explicit A::A() { } // expected-error {{'explicit' can only be specified inside the class definition}}
 explicit A::operator bool() { return false; }  // expected-warning {{explicit conversion functions are a C++11 extension}}\
                                                // expected-error {{'explicit' can only be specified inside the class definition}}
+
+class B {
+  friend explicit A::A(); // expected-error {{'explicit' is invalid in friend declarations}}
+};

Modified: cfe/trunk/test/CXX/drs/dr4xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr4xx.cpp?rev=207682&r1=207681&r2=207682&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr4xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr4xx.cpp Wed Apr 30 13:24:01 2014
@@ -844,14 +844,14 @@ namespace dr474 { // dr474: yes
 
 // dr475 FIXME write a codegen test
 
-namespace dr477 { // dr477: no
+namespace dr477 { // dr477: 3.5
   struct A {
     explicit A();
     virtual void f();
   };
   struct B {
-    friend explicit A::A(); // FIXME: reject this
-    friend virtual void A::f(); // FIXME: reject this
+    friend explicit A::A(); // expected-error {{'explicit' is invalid in friend declarations}}
+    friend virtual void A::f(); // expected-error {{'virtual' is invalid in friend declarations}}
   };
   explicit A::A() {} // expected-error {{can only be specified inside the class definition}}
   virtual void A::f() {} // expected-error {{can only be specified inside the class definition}}

Modified: cfe/trunk/www/cxx_dr_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=207682&r1=207681&r2=207682&view=diff
==============================================================================
--- cfe/trunk/www/cxx_dr_status.html (original)
+++ cfe/trunk/www/cxx_dr_status.html Wed Apr 30 13:24:01 2014
@@ -2903,7 +2903,7 @@ of class templates</td>
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#477">477</a></td>
     <td>CD1</td>
     <td>Can <TT>virtual</TT> appear in a <TT>friend</TT> declaration?</td>
-    <td class="none" align="center">No</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr id="478">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#478">478</a></td>





More information about the cfe-commits mailing list