[llvm-branch-commits] [clang] 6326b09 - [AST][RecoveryExpr] Preserve type for broken overrload member call expr.
Haojian Wu via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Dec 13 23:55:03 PST 2020
Author: Haojian Wu
Date: 2020-12-14T08:50:41+01:00
New Revision: 6326b098852bea51debe415a85eebd1753151cd0
URL: https://github.com/llvm/llvm-project/commit/6326b098852bea51debe415a85eebd1753151cd0
DIFF: https://github.com/llvm/llvm-project/commit/6326b098852bea51debe415a85eebd1753151cd0.diff
LOG: [AST][RecoveryExpr] Preserve type for broken overrload member call expr.
Reviewed By: sammccall
Differential Revision: https://reviews.llvm.org/D80109
Added:
Modified:
clang/lib/Sema/SemaOverload.cpp
clang/test/AST/ast-dump-recovery.cpp
clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 5689efe578fa..13d2125d1a28 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -14300,6 +14300,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
UnbridgedCasts.restore();
OverloadCandidateSet::iterator Best;
+ bool Succeeded = false;
switch (CandidateSet.BestViableFunction(*this, UnresExpr->getBeginLoc(),
Best)) {
case OR_Success:
@@ -14307,7 +14308,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
FoundDecl = Best->FoundDecl;
CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc()))
- return ExprError();
+ break;
// If FoundDecl is
diff erent from Method (such as if one is a template
// and the other a specialization), make sure DiagnoseUseOfDecl is
// called on both.
@@ -14316,7 +14317,8 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
// being used.
if (Method != FoundDecl.getDecl() &&
DiagnoseUseOfDecl(Method, UnresExpr->getNameLoc()))
- return ExprError();
+ break;
+ Succeeded = true;
break;
case OR_No_Viable_Function:
@@ -14326,27 +14328,25 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
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);
diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp
index 2a8346eb0d15..a8da2b8ad449 100644
--- a/clang/test/AST/ast-dump-recovery.cpp
+++ b/clang/test/AST/ast-dump-recovery.cpp
@@ -125,6 +125,9 @@ struct Foo2 {
double func();
class ForwardClass;
ForwardClass createFwd();
+
+ int overload();
+ int overload(int, int);
};
void test2(Foo2 f) {
// CHECK: RecoveryExpr {{.*}} 'double'
@@ -136,6 +139,11 @@ void test2(Foo2 f) {
// 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
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
index ce43720cb2d3..f12e0083fb0c 100644
--- a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
@@ -9,7 +9,7 @@
// 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.
@@ -134,14 +134,14 @@ namespace test3 {
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'}}
}
}
More information about the llvm-branch-commits
mailing list