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