diff options
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 940bccc..c9eb678 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -5664,15 +5664,10 @@ static ImplicitConversionSequence TryObjectArgumentInitialization( assert(FromType->isRecordType()); QualType ClassType = S.Context.getTypeDeclType(ActingContext); - // C++98 [class.dtor]p2: - // A destructor can be invoked for a const, volatile or const volatile - // object. - // C++98 [over.match.funcs]p4: - // For static member functions, the implicit object parameter is considered - // to match any object (since if the function is selected, the object is - // discarded). + // [class.dtor]p2: A destructor can be invoked for a const, volatile or + // const volatile object. Qualifiers Quals = Method->getMethodQualifiers(); - if (isa<CXXDestructorDecl>(Method) || Method->isStatic()) { + if (isa<CXXDestructorDecl>(Method)) { Quals.addConst(); Quals.addVolatile(); } @@ -15066,7 +15061,7 @@ ExprResult Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl); SmallVector<Expr *, 2> MethodArgs; - // Initialize the object parameter. + // Handle 'this' parameter if the selected function is not static. if (Method->isExplicitObjectMemberFunction()) { ExprResult Res = InitializeExplicitObjectArgument(*this, Args[0], Method); @@ -15074,7 +15069,7 @@ ExprResult Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, return ExprError(); Args[0] = Res.get(); ArgExpr = Args; - } else { + } else if (Method->isInstance()) { ExprResult Arg0 = PerformImplicitObjectArgumentInitialization( Args[0], /*Qualifier=*/nullptr, Best->FoundDecl, Method); if (Arg0.isInvalid()) @@ -15102,9 +15097,15 @@ ExprResult Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); - CallExpr *TheCall = CXXOperatorCallExpr::Create( - Context, OO_Subscript, FnExpr.get(), MethodArgs, ResultTy, VK, RLoc, - CurFPFeatureOverrides()); + CallExpr *TheCall; + if (Method->isInstance()) + TheCall = CXXOperatorCallExpr::Create( + Context, OO_Subscript, FnExpr.get(), MethodArgs, ResultTy, VK, + RLoc, CurFPFeatureOverrides()); + else + TheCall = + CallExpr::Create(Context, FnExpr.get(), MethodArgs, ResultTy, VK, + RLoc, CurFPFeatureOverrides()); if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl)) return ExprError(); @@ -15732,13 +15733,15 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, bool IsError = false; - // Initialize the object parameter. + // Initialize the implicit object parameter if needed. + // Since C++23, this could also be a call to a static call operator + // which we emit as a regular CallExpr. llvm::SmallVector<Expr *, 8> NewArgs; if (Method->isExplicitObjectMemberFunction()) { // FIXME: we should do that during the definition of the lambda when we can. DiagnoseInvalidExplicitObjectParameterInLambda(Method); PrepareExplicitObjectArgument(*this, Method, Obj, Args, NewArgs); - } else { + } else if (Method->isInstance()) { ExprResult ObjRes = PerformImplicitObjectArgumentInitialization( Object.get(), /*Qualifier=*/nullptr, Best->FoundDecl, Method); if (ObjRes.isInvalid()) @@ -15772,9 +15775,14 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); - CallExpr *TheCall = CXXOperatorCallExpr::Create( - Context, OO_Call, NewFn.get(), MethodArgs, ResultTy, VK, RParenLoc, - CurFPFeatureOverrides()); + CallExpr *TheCall; + if (Method->isInstance()) + TheCall = CXXOperatorCallExpr::Create(Context, OO_Call, NewFn.get(), + MethodArgs, ResultTy, VK, RParenLoc, + CurFPFeatureOverrides()); + else + TheCall = CallExpr::Create(Context, NewFn.get(), MethodArgs, ResultTy, VK, + RParenLoc, CurFPFeatureOverrides()); if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method)) return true; |