[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.

llvm-svn: 248925
This commit is contained in:
Reid Kleckner 2015-09-30 17:30:48 +00:00
parent 4c45775880
commit 21525e7fd4
2 changed files with 37 additions and 8 deletions

View File

@ -1824,7 +1824,6 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
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, CXXScopeSpec &SS, LookupResult &R,
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, CXXScopeSpec &SS, LookupResult &R,
TemplateArgumentListInfo TList;
if (ULE->hasExplicitTemplateArgs())
ULE->copyTemplateArgumentsInto(TList);
CXXScopeSpec SS;
SS.Adopt(ULE->getQualifierLoc());
CXXDependentScopeMemberExpr *DepExpr =

View File

@ -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() {}
}