Index: lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3808,7 +3808,8 @@ PendingInstantiations.push_back( std::make_pair(Function, PointOfInstantiation)); } else if (TSK == TSK_ImplicitInstantiation) { - if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) { + if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() && + !getSourceManager().isInSystemHeader(PatternDecl->getLocStart())) { Diag(PointOfInstantiation, diag::warn_func_template_missing) << Function; Diag(PatternDecl->getLocation(), diag::note_forward_template_decl); @@ -4338,7 +4339,8 @@ std::make_pair(Var, PointOfInstantiation)); } else if (TSK == TSK_ImplicitInstantiation) { // Warn about missing definition at the end of translation unit. - if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) { + if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() && + !getSourceManager().isInSystemHeader(PatternDecl->getLocStart())) { Diag(PointOfInstantiation, diag::warn_var_template_missing) << Var; Diag(PatternDecl->getLocation(), diag::note_forward_template_decl); Index: test/SemaTemplate/undefined-template.cpp =================================================================== --- test/SemaTemplate/undefined-template.cpp +++ test/SemaTemplate/undefined-template.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 -Wundefined-func-template %s +#if !defined(INCLUDE) template struct C1 { static char s_var_1; // expected-note{{forward declaration of template entity is here}} static char s_var_2; // expected-note{{forward declaration of template entity is here}} @@ -142,6 +143,16 @@ void h(X x) { g(x); } // no warning for use of 'g' despite the declaration having been instantiated from a template } +#define INCLUDE +#include "undefined-template.cpp" +void func_25(SystemHeader *x) { + x->meth(); +} + int main() { return 0; } +#else +#pragma clang system_header +template struct SystemHeader { T meth(); }; +#endif