]> granicus.if.org Git - clang/commitdiff
Implement [dcl.attr.override]p2 and add tests for p1 and p2.
authorAnders Carlsson <andersca@mac.com>
Sun, 17 Oct 2010 23:36:12 +0000 (23:36 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 17 Oct 2010 23:36:12 +0000 (23:36 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116692 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/CXX/dcl.dcl/dcl.attr/dcl.attr.override/p1.cpp [new file with mode: 0644]

index f20c2da4603520aee53ddcfcf92fc3bb05592070..0b82c03da2b59ba7da43d6b735e7440670104024 100644 (file)
@@ -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">;
index 8aae17cc9daffff8d84333266cb0dfb3818001f6..c727c643709996b1eef02634dfa2e953202e31ee 100644 (file)
@@ -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)
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 (file)
index 0000000..3bf9f4f
--- /dev/null
@@ -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}}
+};