[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 28 10:44:09 PST 2024
Botond =?utf-8?q?István_Horváth?=,Botond Istvan Horvath
<horvath.botond.istvan at gmail.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/83279 at github.com>
================
@@ -5548,13 +5504,100 @@ static bool isAtLeastAsSpecializedAs(Sema &S,
FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
- unsigned NumCallArguments2, bool Reversed) {
+ unsigned NumCallArguments2, QualType RawObjType1, QualType RawObjType2,
+ bool Reversed) {
+ SmallVector<QualType, 4> Args1;
+ SmallVector<QualType, 4> Args2;
+ const FunctionDecl *FD1 = FT1->getTemplatedDecl();
+ const FunctionDecl *FD2 = FT2->getTemplatedDecl();
+ bool shouldConvert1 = false;
+ bool shouldConvert2 = false;
+ QualType ObjType1;
+ QualType ObjType2;
+ if (TPOC == TPOC_Call) {
+ const FunctionProtoType *Proto1 =
+ FD1->getType()->getAs<FunctionProtoType>();
+ const FunctionProtoType *Proto2 =
+ FD2->getType()->getAs<FunctionProtoType>();
+
+ // - In the context of a function call, the function parameter types are
+ // used.
+ const CXXMethodDecl *Method1 = dyn_cast<CXXMethodDecl>(FD1);
+ const CXXMethodDecl *Method2 = dyn_cast<CXXMethodDecl>(FD2);
+
+ if (getLangOpts().CPlusPlus20) {
+ // C++20 [temp.func.order]p3
+ // [...] Each function template M that is a member function is
+ // considered to have a new first parameter of type
+ // X(M), described below, inserted in its function parameter list.
+ //
+ // Note that we interpret "that is a member function" as
+ // "that is a member function with no expicit object argument".
+ // Otherwise the ordering rules for methods with expicit objet arguments
+ // against anything else make no sense.
+ shouldConvert1 = Method1 && !Method1->isExplicitObjectMemberFunction();
+ shouldConvert2 = Method2 && !Method2->isExplicitObjectMemberFunction();
+ } else {
+ // C++11 [temp.func.order]p3:
+ // [...] If only one of the function templates is a non-static
+ // member, that function template is considered to have a new
+ // first parameter inserted in its function parameter list.
+ //
+ // Note that we interpret this to mean "if one of the function
+ // templates is a non-static member and the other is a non-member";
+ // otherwise, the ordering rules for static functions against non-static
+ // functions don't make any sense.
+ //
+ // C++98/03 doesn't have this provision but we've extended DR532 to cover
+ // it as wording was broken prior to it.
+ shouldConvert1 =
+ !Method2 && Method1 && Method1->isImplicitObjectMemberFunction();
+ shouldConvert2 =
+ !Method1 && Method2 && Method2->isImplicitObjectMemberFunction();
+ }
+ if (shouldConvert1) {
+ bool isR2 =
+ getLangOpts().CPlusPlus20 &&
+ (shouldConvert1
----------------
erichkeane wrote:
Think this line is a copy/paste error? We already know the value of shouldConvert1 (and 2 below).
https://github.com/llvm/llvm-project/pull/83279
More information about the cfe-commits
mailing list