diff options
author | Anders Carlsson <andersca@mac.com> | 2010-10-17 23:36:12 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-10-17 23:36:12 +0000 |
commit | 4d09e84fbb0305372efc778a6770f0c3a5b5b2ae (patch) | |
tree | 46dbc2dcfbc32b0a3daba9aba33012d2df32841e /lib | |
parent | 7759919062b4e773791f1b49dabf0a509c4a7406 (diff) |
Implement [dcl.attr.override]p2 and add tests for p1 and p2.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116692 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 8aae17cc9d..c727c64370 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3208,6 +3208,28 @@ static void DiagnoseInvalidRedeclaration(Sema &S, FunctionDecl *NewFD) { } } +/// CheckClassMemberNameAttributes - Check for class member name checking +/// attributes according to [dcl.attr.override] +static void +CheckClassMemberNameAttributes(Sema& SemaRef, const FunctionDecl *FD) { + const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD); + if (!MD || !MD->isVirtual()) + return; + + bool HasOverrideAttr = MD->hasAttr<OverrideAttr>(); + bool HasOverriddenMethods = + MD->begin_overridden_methods() != MD->end_overridden_methods(); + + /// C++ [dcl.attr.override]p2: + /// If a virtual member function f is marked override and does not override + /// a member function of a base class the program is ill-formed. + if (HasOverrideAttr && !HasOverriddenMethods) { + SemaRef.Diag(MD->getLocation(), diag::err_override_function_not_overriding) + << MD->getDeclName(); + return; + } +} + NamedDecl* Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, QualType R, TypeSourceInfo *TInfo, @@ -3855,6 +3877,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, MarkUnusedFileScopedDecl(NewFD); + CheckClassMemberNameAttributes(*this, NewFD); + return NewFD; } @@ -6789,7 +6813,7 @@ void Sema::ActOnFields(Scope* S, // Flexible array member. // Microsoft is more permissive regarding flexible array. // It will accept flexible array in union and also - // as the sole element of a struct/class. + // as the sole element of a struct/class. if (getLangOptions().Microsoft) { if (Record->isUnion()) Diag(FD->getLocation(), diag::ext_flexible_array_union) |