diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -175,6 +175,8 @@ SmallVector WorkList = {StartRD}; while (!WorkList.empty()) { const CXXRecordDecl *RD = WorkList.pop_back_val(); + if (RD->isDependentType()) + continue; for (const CXXBaseSpecifier &BaseSpec : RD->bases()) { if (const CXXRecordDecl *B = BaseSpec.getType()->getAsCXXRecordDecl()) { if (!SeenBaseTypes.insert(B).second) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2648,6 +2648,9 @@ if (auto Rec = Type->getAs()) { auto Decl = Rec->getAsCXXRecordDecl(); + if (Decl->isDependentType()) + return; + // Iterate over its bases. for (const auto &BaseSpec : Decl->bases()) { QualType Base = Context.getCanonicalType(BaseSpec.getType()) diff --git a/clang/test/SemaCXX/class.cpp b/clang/test/SemaCXX/class.cpp --- a/clang/test/SemaCXX/class.cpp +++ b/clang/test/SemaCXX/class.cpp @@ -211,3 +211,30 @@ struct PR9989 { static int const PR9989_Member = sizeof PR9989_Member; }; + +namespace dependent_base_type { +struct B1 {}; + +template +struct S0 { + void m0() { + struct B0; // expected-note {{member is declared here}} + + struct D : B0, B1 { // expected-error {{implicit instantiation}} expected-note {{in instantiation of}} + }; + } +}; + +void test() { + S0().m0(); // expected-note {{in instantiation of}} +} + +// clang used to crash compiling this code. +struct A {}; +template +struct X { + struct B : A {}; + struct C : A, B {}; +}; + +} // namespace dependent_base_type