UnbridgedCasts.restore();
OverloadCandidateSet::iterator Best;
+ bool Succeeded = false;
switch (CandidateSet.BestViableFunction(*this, UnresExpr->getBeginLoc(),
Best)) {
case OR_Success:
FoundDecl = Best->FoundDecl;
CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc()))
- return ExprError();
+ break;
// If FoundDecl is different from Method (such as if one is a template
// and the other a specialization), make sure DiagnoseUseOfDecl is
// called on both.
// being used.
if (Method != FoundDecl.getDecl() &&
DiagnoseUseOfDecl(Method, UnresExpr->getNameLoc()))
- return ExprError();
+ break;
+ Succeeded = true;
break;
case OR_No_Viable_Function:
PDiag(diag::err_ovl_no_viable_member_function_in_call)
<< DeclName << MemExprE->getSourceRange()),
*this, OCD_AllCandidates, Args);
- // FIXME: Leaking incoming expressions!
- return ExprError();
-
+ break;
case OR_Ambiguous:
CandidateSet.NoteCandidates(
PartialDiagnosticAt(UnresExpr->getMemberLoc(),
PDiag(diag::err_ovl_ambiguous_member_call)
<< DeclName << MemExprE->getSourceRange()),
*this, OCD_AmbiguousCandidates, Args);
- // FIXME: Leaking incoming expressions!
- return ExprError();
-
+ break;
case OR_Deleted:
CandidateSet.NoteCandidates(
PartialDiagnosticAt(UnresExpr->getMemberLoc(),
PDiag(diag::err_ovl_deleted_member_call)
<< DeclName << MemExprE->getSourceRange()),
*this, OCD_AllCandidates, Args);
- // FIXME: Leaking incoming expressions!
- return ExprError();
+ break;
}
+ // Overload resolution fails, try to recover.
+ if (!Succeeded)
+ return BuildRecoveryExpr(chooseRecoveryType(CandidateSet, &Best));
MemExprE = FixOverloadedFunctionReference(MemExprE, FoundDecl, Method);
double func();
class ForwardClass;
ForwardClass createFwd();
+
+ int overload();
+ int overload(int, int);
};
void test2(Foo2 f) {
// CHECK: RecoveryExpr {{.*}} 'double'
// CHECK-NEXT: `-MemberExpr {{.*}} '<bound member function type>' .createFwd
// CHECK-NEXT: `-DeclRefExpr {{.*}} 'f'
f.createFwd();
+ // CHECK: RecoveryExpr {{.*}} 'int' contains-errors
+ // CHECK-NEXT: |-UnresolvedMemberExpr
+ // CHECK-NEXT: `-DeclRefExpr {{.*}} 'Foo2'
+ // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
+ f.overload(1);
}
// CHECK: |-AlignedAttr {{.*}} alignas
// parameter types in a base class (rather than conflicting).
template <unsigned n> struct Opaque {};
-template <unsigned n> void expect(Opaque<n> _) {}
+template <unsigned n> void expect(Opaque<n> _) {} // expected-note 4 {{candidate function template not viable}}
// PR5727
// This just shouldn't crash.
void test() {
expect<0>(Base().foo<int>());
expect<1>(Base().foo<0>());
- expect<0>(Derived1().foo<int>()); // expected-error {{no matching member function for call to 'foo'}}
+ expect<0>(Derived1().foo<int>()); // expected-error {{no matching member function for call to 'foo'}} expected-error {{no matching function for call to 'expect'}}
expect<2>(Derived1().foo<0>());
- expect<0>(Derived2().foo<int>()); // expected-error {{no matching member function for call to 'foo'}}
+ expect<0>(Derived2().foo<int>()); // expected-error {{no matching member function for call to 'foo'}} expected-error {{no matching function for call to 'expect'}}
expect<2>(Derived2().foo<0>());
expect<3>(Derived3().foo<int>());
- expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}}
+ expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} expected-error {{no matching function for call to 'expect'}}
expect<3>(Derived4().foo<int>());
- expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}}
+ expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} expected-error {{no matching function for call to 'expect'}}
}
}