Implement [dcl.attr.override]p2 and add tests for p1 and p2.

llvm-svn: 116692
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 8aae17c..c727c643 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3208,6 +3208,28 @@
   }
 }
 
+/// 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 @@
 
   MarkUnusedFileScopedDecl(NewFD);
 
+  CheckClassMemberNameAttributes(*this, NewFD);
+
   return NewFD;
 }
 
@@ -6789,7 +6813,7 @@
       // 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)