Hi rnk, rsmith,
This patch does two things in order to enable compilation of the problematic
code in PR23810:
In Sema::buildOverloadedCallSet, it postpones lookup for MS mode when no viable
candidate is found in the overload set. Previously, lookup would only be
postponed here if the overload set was empty.
Make BuildRecoveryCallExpr call Sema::DiagnoseEmptyLookup under more
circumstances. There is a comment in DiagnoseTwoPhaseLookup that says "Don't
diagnose names we find in classes; we get much better diagnostics for these
from DiagnoseEmptyLookup." The problem was that DiagnoseEmptyLookup might not
get called later, and we failed to recover.
Please take a look!
http://reviews.llvm.org/D10369
Files:
lib/Sema/SemaOverload.cpp
test/SemaTemplate/ms-lookup-template-base-classes.cpp
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -10507,7 +10507,8 @@
const CXXScopeSpec &SS, LookupResult &R,
OverloadCandidateSet::CandidateSetKind CSK,
TemplateArgumentListInfo *ExplicitTemplateArgs,
- ArrayRef<Expr *> Args) {
+ ArrayRef<Expr *> Args,
+ bool *DoDiagnoseEmptyLookup = nullptr) {
if (SemaRef.ActiveTemplateInstantiations.empty() || !SS.isEmpty())
return false;
@@ -10524,6 +10525,8 @@
// Don't diagnose names we find in classes; we get much better
// diagnostics for these from DiagnoseEmptyLookup.
R.clear();
+ if (DoDiagnoseEmptyLookup)
+ *DoDiagnoseEmptyLookup = true;
return false;
}
@@ -10673,15 +10676,16 @@
LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
Sema::LookupOrdinaryName);
+ bool DoDiagnoseEmptyLookup = EmptyLookup;
if (!DiagnoseTwoPhaseLookup(SemaRef, Fn->getExprLoc(), SS, R,
OverloadCandidateSet::CSK_Normal,
- ExplicitTemplateArgs, Args) &&
- (!EmptyLookup ||
- SemaRef.DiagnoseEmptyLookup(
- S, SS, R,
- MakeValidator(SemaRef, dyn_cast<MemberExpr>(Fn), Args.size(),
- ExplicitTemplateArgs != nullptr, AllowTypoCorrection),
- ExplicitTemplateArgs, Args)))
+ ExplicitTemplateArgs, Args,
+ &DoDiagnoseEmptyLookup) &&
+ (!DoDiagnoseEmptyLookup || SemaRef.DiagnoseEmptyLookup(
+ S, SS, R,
+ MakeValidator(SemaRef, dyn_cast<MemberExpr>(Fn), Args.size(),
+ ExplicitTemplateArgs != nullptr, AllowTypoCorrection),
+ ExplicitTemplateArgs, Args)))
return ExprError();
assert(!R.empty() && "lookup results empty despite recovery");
@@ -10746,26 +10750,28 @@
// functions, including those from argument-dependent lookup.
AddOverloadedCallCandidates(ULE, Args, *CandidateSet);
- // If we found nothing, try to recover.
- // BuildRecoveryCallExpr diagnoses the error itself, so we just bail
- // out if it fails.
- if (CandidateSet->empty()) {
- // In Microsoft mode, if we are inside a template class member function then
- // create a type dependent CallExpr. The goal is to postpone name lookup
- // to instantiation time to be able to search into type dependent base
- // classes.
- if (getLangOpts().MSVCCompat && CurContext->isDependentContext() &&
- (isa<FunctionDecl>(CurContext) || isa<CXXRecordDecl>(CurContext))) {
- CallExpr *CE = new (Context) CallExpr(Context, Fn, Args,
- Context.DependentTy, VK_RValue,
- RParenLoc);
+ if (getLangOpts().MSVCCompat && CurContext->isDependentContext() &&
+ (isa<FunctionDecl>(CurContext) || isa<CXXRecordDecl>(CurContext))) {
+
+ OverloadCandidateSet::iterator Best;
+ if (CandidateSet->empty() ||
+ CandidateSet->BestViableFunction(*this, Fn->getLocStart(), Best) ==
+ OR_No_Viable_Function) {
+ // In Microsoft mode, if we are inside a template class member function then
+ // create a type dependent CallExpr. The goal is to postpone name lookup
+ // to instantiation time to be able to search into type dependent base
+ // classes.
+ CallExpr *CE = new (Context) CallExpr(
+ Context, Fn, Args, Context.DependentTy, VK_RValue, RParenLoc);
CE->setTypeDependent(true);
*Result = CE;
return true;
}
- return false;
}
+ if (CandidateSet->empty())
+ return false;
+
UnbridgedCasts.restore();
return false;
}
Index: test/SemaTemplate/ms-lookup-template-base-classes.cpp
===================================================================
--- test/SemaTemplate/ms-lookup-template-base-classes.cpp
+++ test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -547,3 +547,19 @@
XXX x; // expected-error {{unknown type name}}
};
}
+
+namespace PR23801 {
+void f(int);
+struct Base {
+ void f(); // expected-note{{must qualify identifier to find this declaration in dependent base class}}
+};
+template <typename T> struct Template : T {
+ void member() {
+ f(); // expected-warning {{found via unqualified lookup into dependent bases}}
+ }
+};
+void test() {
+ Template<Base> x;
+ x.member(); // expected-note{{requested here}}
+};
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits