diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1913,6 +1913,7 @@ SubExpr = skipImplicitTemporary(cast(SubExpr->IgnoreImplicit())->getArg(0)); else if (E->getCastKind() == CK_UserDefinedConversion) { + SubExpr = SubExpr->IgnoreImplicit(); assert((isa(SubExpr) || isa(SubExpr)) && "Unexpected SubExpr for CK_UserDefinedConversion."); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -7786,7 +7786,7 @@ Method->getType()->castAs())) return ExprError(); - return CE; + return CheckForImmediateInvocation(CE, CE->getMethodDecl()); } ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, diff --git a/clang/test/CodeGenCXX/cxx2a-consteval.cpp b/clang/test/CodeGenCXX/cxx2a-consteval.cpp --- a/clang/test/CodeGenCXX/cxx2a-consteval.cpp +++ b/clang/test/CodeGenCXX/cxx2a-consteval.cpp @@ -210,3 +210,36 @@ AggCtor C(i); return C.a + C.b; } + +struct UserConv { + consteval operator int() const noexcept { return 42; } +}; + +// EVAL-FN-LABEL: @_Z13test_UserConvv( +// EVAL-FN-NEXT: entry: +// EVAL-FN-NEXT: ret i32 42 +// +int test_UserConv() { + return UserConv(); +} + +int test_UserConvOverload_helper(int a) { return a; } + +// EVAL-FN-LABEL: @_Z21test_UserConvOverloadv( +// EVAL-FN-NEXT: entry: +// EVAL-FN-NEXT: %call = call i32 @_Z28test_UserConvOverload_helperi(i32 42) +// EVAL-FN-NEXT: ret i32 %call +// +int test_UserConvOverload() { + return test_UserConvOverload_helper(UserConv()); +} + +consteval int test_UserConvOverload_helper_ceval(int a) { return a; } + +// EVAL-FN-LABEL: @_Z27test_UserConvOverload_cevalv( +// EVAL-FN-NEXT: entry: +// EVAL-FN-NEXT: ret i32 42 +// +int test_UserConvOverload_ceval() { + return test_UserConvOverload_helper_ceval(UserConv()); +}