Author: rnk Date: Wed Sep 30 12:30:48 2015 New Revision: 248925 URL: http://llvm.org/viewvc/llvm-project?rev=248925&view=rev Log: [Sema] Avoid crashing during this-> insertion recovery
We get into this bad state when someone defines a new member function for a class but forgets to add the declaration to the class body. Calling the new member function from a member function template of the class will crash during instantiation. Modified: cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/test/SemaTemplate/recovery-crash.cpp Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=248925&r1=248924&r2=248925&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Sep 30 12:30:48 2015 @@ -1824,7 +1824,6 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXS bool isInstance = CurMethod && CurMethod->isInstance() && DC == CurMethod->getParent() && !isDefaultArgument; - // Give a code modification hint to insert 'this->'. // TODO: fixit for inserting 'Base<T>::' in the other cases. @@ -1838,15 +1837,23 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXS CallsUndergoingInstantiation.back()->getCallee()); CXXMethodDecl *DepMethod; - if (CurMethod->isDependentContext()) + if (CurMethod->isDependentContext()) { DepMethod = CurMethod; - else if (CurMethod->getTemplatedKind() == - FunctionDecl::TK_FunctionTemplateSpecialization) - DepMethod = cast<CXXMethodDecl>(CurMethod->getPrimaryTemplate()-> - getInstantiatedFromMemberTemplate()->getTemplatedDecl()); - else + } else if (FunctionTemplateDecl *FTD = + CurMethod->getPrimaryTemplate()) { + // We have a member function template. It may be contained in a + // class template. If so, get the original pattern for the member + // function template. Otherwise, 'this' isn't dependent and we can + // use CurMethod as is. + if (FunctionTemplateDecl *MemberFTD = + FTD->getInstantiatedFromMemberTemplate()) + DepMethod = cast<CXXMethodDecl>(MemberFTD->getTemplatedDecl()); + else + DepMethod = CurMethod; + } else { DepMethod = cast<CXXMethodDecl>( CurMethod->getInstantiatedFromMemberFunction()); + } assert(DepMethod && "No template pattern found"); QualType DepThisType = DepMethod->getThisType(Context); @@ -1856,7 +1863,7 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXS TemplateArgumentListInfo TList; if (ULE->hasExplicitTemplateArgs()) ULE->copyTemplateArgumentsInto(TList); - + CXXScopeSpec SS; SS.Adopt(ULE->getQualifierLoc()); CXXDependentScopeMemberExpr *DepExpr = Modified: cfe/trunk/test/SemaTemplate/recovery-crash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/recovery-crash.cpp?rev=248925&r1=248924&r2=248925&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/recovery-crash.cpp (original) +++ cfe/trunk/test/SemaTemplate/recovery-crash.cpp Wed Sep 30 12:30:48 2015 @@ -35,3 +35,25 @@ namespace PR16225 { g<S>(0); // expected-note {{in instantiation of function template specialization}} } } + +namespace test1 { + template <typename> class ArraySlice {}; + class Foo; + class NonTemplateClass { + void MemberFunction(ArraySlice<Foo>, int); + template <class T> void MemberFuncTemplate(ArraySlice<T>, int); + }; + void NonTemplateClass::MemberFunction(ArraySlice<Foo> resource_data, + int now) { + // expected-note@+1 {{in instantiation of function template specialization 'test1::NonTemplateClass::MemberFuncTemplate<test1::Foo>'}} + MemberFuncTemplate(resource_data, now); + } + template <class T> + void NonTemplateClass::MemberFuncTemplate(ArraySlice<T> resource_data, int) { + // expected-error@+1 {{use of undeclared identifier 'UndeclaredMethod'}} + UndeclaredMethod(resource_data); + } + // expected-error@+2 {{out-of-line definition of 'UndeclaredMethod' does not match any declaration}} + // expected-note@+1 {{must qualify identifier to find this declaration in dependent base class}} + void NonTemplateClass::UndeclaredMethod() {} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits