Author: abataev Date: Tue May 31 01:21:27 2016 New Revision: 271251 URL: http://llvm.org/viewvc/llvm-project?rev=271251&view=rev Log: [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. Modified: cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/SemaTemplate/ms-lookup-template-base-classes.cpp Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=271251&r1=271250&r2=271251&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue May 31 01:21:27 2016 @@ -163,11 +163,17 @@ lookupUnqualifiedTypeNameInBase(Sema &S, auto *TD = TST->getTemplateName().getAsTemplateDecl(); if (!TD) continue; - auto *BasePrimaryTemplate = - dyn_cast_or_null<CXXRecordDecl>(TD->getTemplatedDecl()); - if (!BasePrimaryTemplate) - continue; - BaseRD = BasePrimaryTemplate; + if (auto *BasePrimaryTemplate = + dyn_cast_or_null<CXXRecordDecl>(TD->getTemplatedDecl())) { + if (BasePrimaryTemplate->getCanonicalDecl() != RD->getCanonicalDecl()) + BaseRD = BasePrimaryTemplate; + else if (auto *CTD = dyn_cast<ClassTemplateDecl>(TD)) { + if (const ClassTemplatePartialSpecializationDecl *PS = + CTD->findPartialSpecialization(Base.getType())) + if (PS->getCanonicalDecl() != RD->getCanonicalDecl()) + BaseRD = PS; + } + } } if (BaseRD) { for (NamedDecl *ND : BaseRD->lookup(&II)) { Modified: cfe/trunk/test/SemaTemplate/ms-lookup-template-base-classes.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/ms-lookup-template-base-classes.cpp?rev=271251&r1=271250&r2=271251&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/ms-lookup-template-base-classes.cpp (original) +++ cfe/trunk/test/SemaTemplate/ms-lookup-template-base-classes.cpp Tue May 31 01:21:27 2016 @@ -603,3 +603,32 @@ struct Base { template struct UseUnqualifiedTypeNames<Base>; struct BadBase { }; template struct UseUnqualifiedTypeNames<BadBase>; // expected-note-re 2 {{in instantiation {{.*}} requested here}} + +namespace partial_template_lookup { + +class Bar; +class Spare; + +template <class T, class X = Bar> +class FooTemplated; + +class FooBase { +public: + typedef int BaseTypedef; +}; + +// Partial template spec (unused) +template <class T> +class FooTemplated<T, Spare> {}; + +// Partial template spec (used) +template <class T> +class FooTemplated<T, Bar> : public FooBase {}; + +// Full template spec +template <class T, class X> +class FooTemplated : public FooTemplated<T, Bar> { +public: + BaseTypedef Member; // expected-warning {{unqualified lookup}} +}; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits