Index: include/clang/AST/DeclTemplate.h
===================================================================
--- include/clang/AST/DeclTemplate.h	(revision 230518)
+++ include/clang/AST/DeclTemplate.h	(working copy)
@@ -1453,6 +1453,8 @@
   static ClassTemplateSpecializationDecl *
   CreateDeserialized(ASTContext &C, unsigned ID);
 
+  bool IsMethodInInstantiatedRecordType(const CXXMethodDecl *MD) const;
+    
   void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
                             bool Qualified) const override;
 
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 230518)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -5213,7 +5213,8 @@
     
   /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was
   /// not used in the declaration of an overriding method.
-  void DiagnoseAbsenceOfOverrideControl(NamedDecl *D);
+  void DiagnoseAbsenceOfOverrideControl(const CXXRecordDecl *Record,
+                                        NamedDecl *D);
 
   /// CheckForFunctionMarkedFinal - Checks whether a virtual member function
   /// overrides a virtual member function marked 'final', according to
Index: lib/AST/DeclTemplate.cpp
===================================================================
--- lib/AST/DeclTemplate.cpp	(revision 230518)
+++ lib/AST/DeclTemplate.cpp	(working copy)
@@ -875,6 +875,29 @@
   return Result;
 }
 
+/// \brief Check if method is in a class which is used as a type to instantiate
+/// the template, return true.
+bool
+ClassTemplateSpecializationDecl::IsMethodInInstantiatedRecordType(
+                                                const CXXMethodDecl *MD) const
+{
+  const TemplateArgumentList &TemplateArgs = getTemplateInstantiationArgs();
+  for (int i=0, e = TemplateArgs.size(); i != e; ++i) {
+    const TemplateArgument &Arg = TemplateArgs.get(i);
+    TemplateArgument::ArgKind kind = Arg.getKind();
+    if (kind == TemplateArgument::Type) {
+      QualType T = Arg.getAsType();
+      if (const CXXRecordDecl *CD = T->getAsCXXRecordDecl()) {
+        const CXXRecordDecl *CDecl = MD->getParent();
+        return (CD->getCanonicalDecl() == CDecl->getCanonicalDecl()) ||
+               CD->isDerivedFrom(CDecl);
+      }
+    }
+  }
+  
+  return false;
+}
+
 //===----------------------------------------------------------------------===//
 // FriendTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp	(revision 230518)
+++ lib/Sema/SemaDeclCXX.cpp	(working copy)
@@ -1946,14 +1946,30 @@
       << MD->getDeclName();
 }
 
-void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D) {
+void Sema::DiagnoseAbsenceOfOverrideControl(const CXXRecordDecl *Record,
+                                            NamedDecl *D) {
   if (D->isInvalidDecl() || D->hasAttr<OverrideAttr>())
     return;
   CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D);
   if (!MD || MD->isImplicit() || MD->hasAttr<FinalAttr>() ||
       isa<CXXDestructorDecl>(MD))
     return;
+  
+  // We cannot reason about instantiated methods with dependent types.
+  if (MD->isTemplateInstantiation())
+    if (FunctionDecl *TFD = MD->getTemplateInstantiationPattern())
+      if (TFD->getType()->isDependentType())
+        return;
 
+  // If overridden method is in a class which is an instantiation
+  // type of the template, we cannot reason about it.
+  if (const ClassTemplateSpecializationDecl *CTSD =
+      dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
+    if (MD->size_overridden_methods() > 0 &&
+        CTSD->IsMethodInInstantiatedRecordType(*MD->begin_overridden_methods()))
+      return;
+  }
+  
   SourceLocation Loc = MD->getLocation();
   SourceLocation SpellingLoc = Loc;
   if (getSourceManager().isMacroArgExpansion(Loc))
@@ -4952,7 +4968,7 @@
     // At least one method has the 'override' control declared.
     // Diagnose all other overridden methods which do not have 'override' specified on them.
     for (auto *M : Record->methods())
-      DiagnoseAbsenceOfOverrideControl(M);
+      DiagnoseAbsenceOfOverrideControl(Record, M);
   }
 
   // ms_struct is a request to use the same ABI rules as MSVC.  Check
Index: test/SemaCXX/no-missing-override-warning.cpp
===================================================================
--- test/SemaCXX/no-missing-override-warning.cpp	(revision 0)
+++ test/SemaCXX/no-missing-override-warning.cpp	(working copy)
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s -std=c++11
+// pr22582
+// rdar://19917107
+
+struct S {
+    virtual void F(int) {}
+    virtual void F2() = 0;
+    virtual void F3(double) {} // expected-note 2 {{overridden virtual function is here}}
+};
+
+template <typename T>
+struct D : S {
+    void F(T)  {}
+    void F2() override {}
+    void F3(double) {} // expected-warning 2 {{'F3' overrides a member function but is not marked 'override'}}
+};
+
+void Test1() {
+  D<int> d; // expected-note {{in instantiation of template class 'D<int>' requested here}}
+  D<double> d2; // expected-note {{in instantiation of template class 'D<double>' requested here}}
+}
+
+struct base {
+  virtual ~base();
+  virtual void func();
+};
+
+template<typename T> struct D1: T {
+  void func();
+  ~D1() override;
+};
+
+void Test2() {
+  D1<base> d;
+}
+
+template <typename Base> struct D2 : Base {
+  void some_override() override;
+  void foo();
+};
+
+struct Base1 {
+  virtual void some_override();
+  virtual void foo();
+};
+
+struct Base2 {
+  virtual void some_override();
+};
+
+void Test3() {
+  D2<Base1> d1;
+  D2<Base2> d2;
+}
+
+template <typename T> struct D3 : T {
+  void some_override() override;
+  void foo();
+};
+
+struct Base3 : Base1 {
+  virtual void some_override();
+};
+
+void Test4() {
+  D3<Base3> d1;
+  D3<Base2> d2;
+}
