зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
7759919062
Коммит
4d09e84fbb
|
@ -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">;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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}}
|
||||
};
|
Загрузка…
Ссылка в новой задаче