[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:
parent
4c45775880
commit
21525e7fd4
|
@ -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 =
|
||||
|
|
|
@ -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() {}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue