From: Nick Lewycky Date: Fri, 20 Aug 2010 20:54:15 +0000 (+0000) Subject: Add a workaround for PR7947, a crash trying to recover from invalid C++ code. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d9ca4ab3ed3637e97a19d716aa9fbd54c6a5f698;p=clang Add a workaround for PR7947, a crash trying to recover from invalid C++ code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111675 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 15e0f7f1c7..487b9e62f4 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -892,25 +892,30 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, // TODO: fixit for inserting 'Base::' in the other cases. // Actually quite difficult! if (isInstance) { - Diag(R.getNameLoc(), diagnostic) << Name - << FixItHint::CreateInsertion(R.getNameLoc(), "this->"); - UnresolvedLookupExpr *ULE = cast( CallsUndergoingInstantiation.back()->getCallee()); - CXXMethodDecl *DepMethod = cast( + CXXMethodDecl *DepMethod = cast_or_null( CurMethod->getInstantiatedFromMemberFunction()); - QualType DepThisType = DepMethod->getThisType(Context); - CXXThisExpr *DepThis = new (Context) CXXThisExpr(R.getNameLoc(), - DepThisType, false); - TemplateArgumentListInfo TList; - if (ULE->hasExplicitTemplateArgs()) - ULE->copyTemplateArgumentsInto(TList); - CXXDependentScopeMemberExpr *DepExpr = - CXXDependentScopeMemberExpr::Create( - Context, DepThis, DepThisType, true, SourceLocation(), - ULE->getQualifier(), ULE->getQualifierRange(), NULL, - R.getLookupNameInfo(), &TList); - CallsUndergoingInstantiation.back()->setCallee(DepExpr); + if (DepMethod) { + Diag(R.getNameLoc(), diagnostic) << Name + << FixItHint::CreateInsertion(R.getNameLoc(), "this->"); + QualType DepThisType = DepMethod->getThisType(Context); + CXXThisExpr *DepThis = new (Context) CXXThisExpr( + R.getNameLoc(), DepThisType, false); + TemplateArgumentListInfo TList; + if (ULE->hasExplicitTemplateArgs()) + ULE->copyTemplateArgumentsInto(TList); + CXXDependentScopeMemberExpr *DepExpr = + CXXDependentScopeMemberExpr::Create( + Context, DepThis, DepThisType, true, SourceLocation(), + ULE->getQualifier(), ULE->getQualifierRange(), NULL, + R.getLookupNameInfo(), &TList); + CallsUndergoingInstantiation.back()->setCallee(DepExpr); + } else { + // FIXME: we should be able to handle this case too. It is correct + // to add this-> here. This is a workaround for PR7947. + Diag(R.getNameLoc(), diagnostic) << Name; + } } else { Diag(R.getNameLoc(), diagnostic) << Name; } diff --git a/test/SemaTemplate/recovery-crash.cpp b/test/SemaTemplate/recovery-crash.cpp new file mode 100644 index 0000000000..0ed3258b68 --- /dev/null +++ b/test/SemaTemplate/recovery-crash.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// We don't expect a fix-it to be applied in this case. Clang used to crash +// trying to recover while adding 'this->' before Work(x); + +template struct A { + static void Work(int); // expected-note{{must qualify identifier}} +}; + +template struct B : public A { + template B(T2 x) { + Work(x); // expected-error{{use of undeclared identifier}} + } +}; + +void Test() { + B b(0); // expected-note{{in instantiation of function template}} +} +