r248925 - [Sema] Avoid crashing during this-> insertion recovery
Reid Kleckner via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 30 10:30:48 PDT 2015
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 at +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 at +1 {{use of undeclared identifier 'UndeclaredMethod'}}
+ UndeclaredMethod(resource_data);
+ }
+ // expected-error at +2 {{out-of-line definition of 'UndeclaredMethod' does not match any declaration}}
+ // expected-note at +1 {{must qualify identifier to find this declaration in dependent base class}}
+ void NonTemplateClass::UndeclaredMethod() {}
+}
More information about the cfe-commits
mailing list