diff options
author | Anders Carlsson <andersca@mac.com> | 2011-01-20 05:57:14 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2011-01-20 05:57:14 +0000 |
commit | 9e682d9f567a51f26c3b0673837e23bafdb09c11 (patch) | |
tree | 00307ce64f4d2641e7cfd8cd18a9f3a2cad98d52 /lib/Sema/SemaDeclCXX.cpp | |
parent | c7119a871df4d2d79db3e48fc9d0ab421be54a3d (diff) |
Diagnose virtual member functions marked override but not overriding any virtual member functions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123888 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index c58fbce5de..8fe4852890 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -852,6 +852,27 @@ Decl *Sema::ActOnAccessSpecifier(AccessSpecifier Access, return ASDecl; } +/// CheckOverrideControl - Check C++0x override control semantics. +static void +CheckOverrideControl(Sema& SemaRef, const Decl *D) { + const CXXMethodDecl *MD = llvm::dyn_cast<CXXMethodDecl>(D); + if (!MD || !MD->isVirtual()) + return; + + // C++0x [class.virtual]p3: + // If a virtual function is marked with the virt-specifier override and does + // not override a member function of a base class, + // the program is ill-formed. + bool HasOverriddenMethods = + MD->begin_overridden_methods() != MD->end_overridden_methods(); + if (MD->isMarkedOverride() && !HasOverriddenMethods) { + SemaRef.Diag(MD->getLocation(), + diag::err_function_marked_override_not_overriding) + << MD->getDeclName(); + return; + } +} + /// ActOnCXXMemberDeclarator - This is invoked when a C++ class member /// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the /// bitfield width if there is one and 'InitExpr' specifies the initializer if @@ -995,7 +1016,8 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, Diag(Member->getLocStart(), diag::override_keyword_only_allowed_on_virtual_member_functions) << "override" << FixItHint::CreateRemoval(VS.getOverrideLoc()); - } + } else + MD->setIsMarkedOverride(true); } if (VS.isFinalSpecified()) { CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member); @@ -1003,8 +1025,12 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, Diag(Member->getLocStart(), diag::override_keyword_only_allowed_on_virtual_member_functions) << "final" << FixItHint::CreateRemoval(VS.getFinalLoc()); - } + } else + MD->setIsMarkedFinal(true); } + + CheckOverrideControl(*this, Member); + assert((Name || isInstField) && "No identifier for non-field ?"); if (Init) |