diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15108,10 +15108,12 @@ } FunctionDecl *FD = nullptr; + bool IsFnTemplate = false; - if (FunctionTemplateDecl *FunTmpl = dyn_cast(D)) + if (FunctionTemplateDecl *FunTmpl = dyn_cast(D)) { FD = FunTmpl->getTemplatedDecl(); - else + IsFnTemplate = true; + } else FD = cast(D); // Do not push if it is a lambda because one is already pushed when building @@ -15260,7 +15262,7 @@ // state is complete. if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() && FD->getFormalLinkage() == Linkage::ExternalLinkage && - !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete && + !FD->isInvalidDecl() && !IsFnTemplate && BodyKind != FnBodyKind::Delete && BodyKind != FnBodyKind::Default && !FD->isInlined()) { assert(FD->isThisDeclarationADefinition()); Diag(FD->getLocation(), diag::err_extern_def_in_header_unit); diff --git a/clang/test/CXX/module/module.import/p6.cpp b/clang/test/CXX/module/module.import/p6.cpp --- a/clang/test/CXX/module/module.import/p6.cpp +++ b/clang/test/CXX/module/module.import/p6.cpp @@ -22,6 +22,8 @@ int bad_var_definition = 3; // expected-error {{non-inline external definitions are not permitted in C++ header units}} +/* The cases below should compile without diagnostics. */ + class A { public: // This is a declaration instead of definition. @@ -36,3 +38,10 @@ S(S&); }; S::S(S&) = default; + +template +int tmpl_OK (_Ep) { return 0; } + +template +bool +operator==(_T1& , _T1& ) { return false; }