From c8dc8c54440cd1e51effdc40d7825f434c12dec4 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Tue, 31 May 2016 06:21:27 +0000 Subject: [PATCH] [MSVC] Fix stack overflow in unqualified type lookup logic, by Will Wilson. An unqualified lookup for in base classes may cause stack overflow if the base class is a specialization of current class. Patch by Will Wilson. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@271251 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 16 ++++++---- .../ms-lookup-template-base-classes.cpp | 29 +++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index f845a65a00..64da16add1 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -163,11 +163,17 @@ lookupUnqualifiedTypeNameInBase(Sema &S, const IdentifierInfo &II, auto *TD = TST->getTemplateName().getAsTemplateDecl(); if (!TD) continue; - auto *BasePrimaryTemplate = - dyn_cast_or_null(TD->getTemplatedDecl()); - if (!BasePrimaryTemplate) - continue; - BaseRD = BasePrimaryTemplate; + if (auto *BasePrimaryTemplate = + dyn_cast_or_null(TD->getTemplatedDecl())) { + if (BasePrimaryTemplate->getCanonicalDecl() != RD->getCanonicalDecl()) + BaseRD = BasePrimaryTemplate; + else if (auto *CTD = dyn_cast(TD)) { + if (const ClassTemplatePartialSpecializationDecl *PS = + CTD->findPartialSpecialization(Base.getType())) + if (PS->getCanonicalDecl() != RD->getCanonicalDecl()) + BaseRD = PS; + } + } } if (BaseRD) { for (NamedDecl *ND : BaseRD->lookup(&II)) { diff --git a/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/test/SemaTemplate/ms-lookup-template-base-classes.cpp index 51d19cef38..6afc709126 100644 --- a/test/SemaTemplate/ms-lookup-template-base-classes.cpp +++ b/test/SemaTemplate/ms-lookup-template-base-classes.cpp @@ -603,3 +603,32 @@ struct Base { template struct UseUnqualifiedTypeNames; struct BadBase { }; template struct UseUnqualifiedTypeNames; // expected-note-re 2 {{in instantiation {{.*}} requested here}} + +namespace partial_template_lookup { + +class Bar; +class Spare; + +template +class FooTemplated; + +class FooBase { +public: + typedef int BaseTypedef; +}; + +// Partial template spec (unused) +template +class FooTemplated {}; + +// Partial template spec (used) +template +class FooTemplated : public FooBase {}; + +// Full template spec +template +class FooTemplated : public FooTemplated { +public: + BaseTypedef Member; // expected-warning {{unqualified lookup}} +}; +} -- 2.50.1