From: Anders Carlsson Date: Sun, 17 Oct 2010 23:36:12 +0000 (+0000) Subject: Implement [dcl.attr.override]p2 and add tests for p1 and p2. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4d09e84fbb0305372efc778a6770f0c3a5b5b2ae;p=clang 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 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index f20c2da460..0b82c03da2 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -830,6 +830,10 @@ def err_final_function_overridden : Error< def err_final_base : Error< "derivation from 'final' %0">; +// C++0x [[override]] +def err_override_function_not_overriding : Error< + "%0 marked 'override' but does not override any member functions">; + // C++0x scoped enumerations def err_enum_invalid_underlying : Error< "non-integral type %0 is an invalid underlying type">; 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(FD); + if (!MD || !MD->isVirtual()) + return; + + bool HasOverrideAttr = MD->hasAttr(); + 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) diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.override/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.override/p1.cpp new file mode 100644 index 0000000000..3bf9f4f0cf --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.override/p1.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +struct A { + virtual void f(); + virtual void h(); +}; + +struct B : A { + [[override]] virtual void f(); + [[override]] void g(); // expected-error {{'override' attribute only applies to virtual method types}} + [[override, override]] void h(); // expected-error {{'override' attribute cannot be repeated}} +};