RecoveryExpr::RecoveryExpr(ASTContext &Ctx, QualType T, SourceLocation BeginLoc,
SourceLocation EndLoc, ArrayRef<Expr *> SubExprs)
- : Expr(RecoveryExprClass, T, VK_LValue, OK_Ordinary), BeginLoc(BeginLoc),
- EndLoc(EndLoc), NumExprs(SubExprs.size()) {
+ : Expr(RecoveryExprClass, T.getNonReferenceType(),
+ T->isDependentType() ? VK_LValue : getValueKindForType(T),
+ OK_Ordinary),
+ BeginLoc(BeginLoc), EndLoc(EndLoc), NumExprs(SubExprs.size()) {
assert(!T.isNull());
assert(llvm::all_of(SubExprs, [](Expr* E) { return E != nullptr; }));
case Expr::UnresolvedLookupExprClass:
case Expr::UnresolvedMemberExprClass:
case Expr::TypoExprClass:
- case Expr::RecoveryExprClass:
case Expr::DependentCoawaitExprClass:
case Expr::CXXDependentScopeMemberExprClass:
case Expr::DependentScopeDeclRefExprClass:
return Cl::CL_PRValue;
}
+ case Expr::RecoveryExprClass:
case Expr::OpaqueValueExprClass:
return ClassifyExprValueKind(Lang, E, E->getValueKind());
auto ConsiderCandidate = [&](const OverloadCandidate &Candidate) {
if (!Candidate.Function)
return;
- QualType T = Candidate.Function->getCallResultType();
+ QualType T = Candidate.Function->getReturnType();
if (T.isNull())
return;
if (!Result)
int some_func(int *);
// CHECK: VarDecl {{.*}} invalid_call
-// CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'int' contains-errors
// CHECK-NEXT: `-RecoveryExpr {{.*}} 'int' contains-errors
// CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func'
// CHECK-NEXT: `-IntegerLiteral {{.*}} 123
int ambig_func(float);
// CHECK: VarDecl {{.*}} ambig_call
-// CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'int' contains-errors
// CHECK-NEXT: `-RecoveryExpr {{.*}} 'int' contains-errors
// CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'ambig_func'
// CHECK-NEXT: `-IntegerLiteral {{.*}} 123
} NoCrashOnInvalidInitList = {
.abc = nullptr,
};
+
+// Verify the value category of recovery expression.
+int prvalue(int);
+int &lvalue(int);
+int &&xvalue(int);
+void ValueCategory() {
+ // CHECK: RecoveryExpr {{.*}} 'int' contains-errors
+ prvalue(); // call to a function (nonreference return type) yields a prvalue (not print by default)
+ // CHECK: RecoveryExpr {{.*}} 'int' contains-errors lvalue
+ lvalue(); // call to a function (lvalue reference return type) yields an lvalue.
+ // CHECK: RecoveryExpr {{.*}} 'int' contains-errors xvalue
+ xvalue(); // call to a function (rvalue reference return type) yields an xvalue.
+}
// expected-note {{in instantiation of member function}} \
// expected-note {{in call to}}
}
+
+// verify no assertion failure on violating value category.
+namespace test4 {
+int &&f(int); // expected-note {{candidate function not viable}}
+int &&k = f(); // expected-error {{no matching function for call}}
+}