Index: include/clang/AST/DeclTemplate.h =================================================================== --- include/clang/AST/DeclTemplate.h +++ include/clang/AST/DeclTemplate.h @@ -236,7 +236,7 @@ TemplateParams(nullptr) {} // Construct a template decl with the given name and parameters. - // Used when there is not templated element (tt-params, alias?). + // Used when there is not templated element (tt-params). TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params) : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr), Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -152,15 +152,17 @@ auto *TD = TST->getTemplateName().getAsTemplateDecl(); if (!TD) continue; - auto *BasePrimaryTemplate = cast(TD->getTemplatedDecl()); - // FIXME: Allow lookup into non-dependent bases of dependent bases, possibly - // by calling or integrating with the main LookupQualifiedName mechanism. - for (NamedDecl *ND : BasePrimaryTemplate->lookup(&II)) { - if (FoundTypeDecl) - return ParsedType(); - FoundTypeDecl = isa(ND); - if (!FoundTypeDecl) - return ParsedType(); + if (CXXRecordDecl *BasePrimaryTemplate = + dyn_cast_or_null(TD->getTemplatedDecl())) { + // FIXME: Allow lookup into non-dependent bases of dependent bases, possibly + // by calling or integrating with the main LookupQualifiedName mechanism. + for (NamedDecl *ND : BasePrimaryTemplate->lookup(&II)) { + if (FoundTypeDecl) + return ParsedType(); + FoundTypeDecl = isa(ND); + if (!FoundTypeDecl) + return ParsedType(); + } } } if (!FoundTypeDecl) Index: test/SemaTemplate/ms-lookup-template-base-classes.cpp =================================================================== --- test/SemaTemplate/ms-lookup-template-base-classes.cpp +++ test/SemaTemplate/ms-lookup-template-base-classes.cpp @@ -460,3 +460,27 @@ int x = f(); }; } + +namespace PR20716 { +template