[clang] Avoid printing overly large integer. (PR #75902)

2023-12-19 Thread Botond István Horváth via cfe-commits


@@ -17132,6 +17132,9 @@ static bool ConvertAPValueToString(const APValue &V, 
QualType T,
 case BuiltinType::WChar_U: {
   unsigned TyWidth = Context.getIntWidth(T);
   assert(8 <= TyWidth && TyWidth <= 32 && "Unexpected integer width");
+  if (V.getInt() >= (1 << 64)) {

HoBoIs wrote:

In 1 << 64 you operates with ints(32 bit). (1 is an int) 1<<64 is results 0. I 
suggest to compare V.getInt() with std::numeric_limits\::max()} 
instead. (or uint64_t(-1)).

https://github.com/llvm/llvm-project/pull/75902
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Avoid printing overly large integer. (PR #75902)

2023-12-19 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs edited https://github.com/llvm/llvm-project/pull/75902
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [NFC][CLANG] Fix null pointer dereferences (PR #86760)

2024-03-27 Thread Botond István Horváth via cfe-commits

HoBoIs wrote:

Looks good to me.

https://github.com/llvm/llvm-project/pull/86760
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-05 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/83279

From 68200ecf3267d1b3940fa73c25c50ee706932a98 Mon Sep 17 00:00:00 2001
From: Botond Istvan Horvath 
Date: Wed, 28 Feb 2024 13:09:15 +0100
Subject: [PATCH 01/10] Bugfix for choosing the more specialized overload

There was a bug in clang where it couldn't choose which overload candidate is
more specialized if it was comparing a member-function to a non-member
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template
transformation described in [temp.func.order] paragraph 3 from
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the
transformed parameter list during the whole comperrassion. Also, to be able
to add the correct type for the implicit object parameter
Sema::getMoreSpecializedTemplate has new parameters for the object type.
---
 clang/include/clang/Sema/Sema.h  |   4 +-
 clang/lib/Sema/SemaOverload.cpp  |  12 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp | 263 +++
 3 files changed, 186 insertions(+), 93 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ef4b93fac95ce5..1a2a3a6bebd95e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9463,7 +9463,9 @@ class Sema final {
   FunctionTemplateDecl *getMoreSpecializedTemplate(
   FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
   TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-  unsigned NumCallArguments2, bool Reversed = false);
+  unsigned NumCallArguments2, QualType ObjType1 = {},
+  QualType ObjType2 = {}, bool Reversed = false);
+
   UnresolvedSetIterator
   getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
  TemplateSpecCandidateSet &FailedCandidates,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d38043890ca20..60138236abf1d8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10526,14 +10526,24 @@ bool clang::isBetterOverloadCandidate(
   //  according to the partial ordering rules described in 14.5.5.2, or,
   //  if not that,
   if (Cand1IsSpecialization && Cand2IsSpecialization) {
+const auto *ObjContext1 =
+dyn_cast(Cand1.FoundDecl->getDeclContext());
+const auto *ObjContext2 =
+dyn_cast(Cand2.FoundDecl->getDeclContext());
 if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(
 Cand1.Function->getPrimaryTemplate(),
 Cand2.Function->getPrimaryTemplate(), Loc,
 isa(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
 Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments,
-Cand1.isReversed() ^ Cand2.isReversed()))
+ObjContext1 ? QualType(ObjContext1->getTypeForDecl(), 0)
+: QualType{},
+ObjContext2 ? QualType(ObjContext2->getTypeForDecl(), 0)
+: QualType{},
+Cand1.isReversed() ^ Cand2.isReversed())) {
   return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+}
+
   }
 
   //   -— F1 and F2 are non-template functions with the same
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 563491f76f5478..2af3c29ae1f1c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5333,11 +5333,31 @@ bool 
Sema::CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
   return false;
 }
 
+static QualType GetImplicitObjectParameterTypeCXX20(ASTContext &Context,
+const CXXMethodDecl 
*Method,
+QualType rawType,
+bool isOtherRvr) {
+  // C++20 [temp.func.order]p3.1, p3.2:
+  //- The type X(M ) is “rvalue reference to cv A” if the optional 
ref-qualifier
+  //  of M is && or if M has no ref-qualifier and the 
positionally-corresponding
+  //  parameter of the other transformed template has rvalue reference type;
+  //  if this determination depends recursively upon whether X(M ) is an rvalue
+  //  reference type, it is not considered to have rvalue reference type.
+  //- Otherwise, X(M ) is “lvalue reference to cv A”.
+  assert(Method && !Method->isExplicitObjectMemberFunction() &&
+ "expected a member function with no explicit object parameter");
+
+  rawType = Context.getQualifiedType(rawType, Method->getMethodQualifiers());
+  if (Method->getRefQualifier() == RQ_RValue ||
+  (isOtherRvr && Method->getRefQualifier() == RQ_None))
+return Context.getRValueReferenceType(rawType);
+  return Context.getLValueReferenceTyp

[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-05 Thread Botond István Horváth via cfe-commits


@@ -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 Args1;
+  SmallVector 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();
+const FunctionProtoType *Proto2 =
+FD2->getType()->getAs();
+
+//   - In the context of a function call, the function parameter types are
+// used.
+const CXXMethodDecl *Method1 = dyn_cast(FD1);
+const CXXMethodDecl *Method2 = dyn_cast(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
+   ? Method2->getRefQualifier() == RQ_RValue
+   : Proto2->param_type_begin()[0]->isRValueReferenceType());
+  // Compare 'this' from Method1 against first parameter from Method2.
+  ObjType1 = GetImplicitObjectParameterType(this->Context, Method1,
+RawObjType1, isR2);
+  Args1.push_back(ObjType1);
+}
+if (shouldConvert2) {
+  bool isR1 =
+  getLangOpts().CPlusPlus20 &&
+  (shouldConvert2
+   ? Method1->getRefQualifier() == RQ_RValue
+   : Proto1->param_type_begin()[0]->isRValueReferenceType());
+  // Compare 'this' from Method2 against first parameter from Method1.
+  ObjType2 = GetImplicitObjectParameterType(this->Context, Method2,
+RawObjType2, isR1);
+  Args2.push_back(ObjType2);
+}
+unsigned NumComparedArguments = NumCallArguments1 + shouldConvert1;
 
-  bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC,
-  NumCallArguments1, Reversed);
-  bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC,
-  NumCallArguments2, Reversed);
+Args1.insert(Args1.end(), Proto1->param_type_begin(),
+ Proto1->param_type_end());
+Args2.insert(Args2.end(), Proto2->param_type_begin(),
+ Proto2->param_type_end());
 
+// C++ [temp.func.order]p5:
+//   The presence of unused ellipsis and default arguments has no effect on
+//   the partial ordering of function templates.
+if (Args1.size() > NumComparedArguments)

HoBoIs wrote:

Done

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-05 Thread Botond István Horváth via cfe-commits

HoBoIs wrote:

@erichkeane Thank you for the suggestions, I have removed the checking for 
C++20 and I also changed to the `Args.resize(std::min(...))` based on what you 
suggested. Is there anything else to be done?

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-06 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/83279

From 68200ecf3267d1b3940fa73c25c50ee706932a98 Mon Sep 17 00:00:00 2001
From: Botond Istvan Horvath 
Date: Wed, 28 Feb 2024 13:09:15 +0100
Subject: [PATCH 01/11] Bugfix for choosing the more specialized overload

There was a bug in clang where it couldn't choose which overload candidate is
more specialized if it was comparing a member-function to a non-member
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template
transformation described in [temp.func.order] paragraph 3 from
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the
transformed parameter list during the whole comperrassion. Also, to be able
to add the correct type for the implicit object parameter
Sema::getMoreSpecializedTemplate has new parameters for the object type.
---
 clang/include/clang/Sema/Sema.h  |   4 +-
 clang/lib/Sema/SemaOverload.cpp  |  12 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp | 263 +++
 3 files changed, 186 insertions(+), 93 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ef4b93fac95ce5..1a2a3a6bebd95e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9463,7 +9463,9 @@ class Sema final {
   FunctionTemplateDecl *getMoreSpecializedTemplate(
   FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
   TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-  unsigned NumCallArguments2, bool Reversed = false);
+  unsigned NumCallArguments2, QualType ObjType1 = {},
+  QualType ObjType2 = {}, bool Reversed = false);
+
   UnresolvedSetIterator
   getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
  TemplateSpecCandidateSet &FailedCandidates,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d38043890ca20..60138236abf1d8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10526,14 +10526,24 @@ bool clang::isBetterOverloadCandidate(
   //  according to the partial ordering rules described in 14.5.5.2, or,
   //  if not that,
   if (Cand1IsSpecialization && Cand2IsSpecialization) {
+const auto *ObjContext1 =
+dyn_cast(Cand1.FoundDecl->getDeclContext());
+const auto *ObjContext2 =
+dyn_cast(Cand2.FoundDecl->getDeclContext());
 if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(
 Cand1.Function->getPrimaryTemplate(),
 Cand2.Function->getPrimaryTemplate(), Loc,
 isa(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
 Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments,
-Cand1.isReversed() ^ Cand2.isReversed()))
+ObjContext1 ? QualType(ObjContext1->getTypeForDecl(), 0)
+: QualType{},
+ObjContext2 ? QualType(ObjContext2->getTypeForDecl(), 0)
+: QualType{},
+Cand1.isReversed() ^ Cand2.isReversed())) {
   return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+}
+
   }
 
   //   -— F1 and F2 are non-template functions with the same
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 563491f76f5478..2af3c29ae1f1c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5333,11 +5333,31 @@ bool 
Sema::CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
   return false;
 }
 
+static QualType GetImplicitObjectParameterTypeCXX20(ASTContext &Context,
+const CXXMethodDecl 
*Method,
+QualType rawType,
+bool isOtherRvr) {
+  // C++20 [temp.func.order]p3.1, p3.2:
+  //- The type X(M ) is “rvalue reference to cv A” if the optional 
ref-qualifier
+  //  of M is && or if M has no ref-qualifier and the 
positionally-corresponding
+  //  parameter of the other transformed template has rvalue reference type;
+  //  if this determination depends recursively upon whether X(M ) is an rvalue
+  //  reference type, it is not considered to have rvalue reference type.
+  //- Otherwise, X(M ) is “lvalue reference to cv A”.
+  assert(Method && !Method->isExplicitObjectMemberFunction() &&
+ "expected a member function with no explicit object parameter");
+
+  rawType = Context.getQualifiedType(rawType, Method->getMethodQualifiers());
+  if (Method->getRefQualifier() == RQ_RValue ||
+  (isOtherRvr && Method->getRefQualifier() == RQ_None))
+return Context.getRValueReferenceType(rawType);
+  return Context.getLValueReferenceTyp

[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-06 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/83279

From 68200ecf3267d1b3940fa73c25c50ee706932a98 Mon Sep 17 00:00:00 2001
From: Botond Istvan Horvath 
Date: Wed, 28 Feb 2024 13:09:15 +0100
Subject: [PATCH 01/12] Bugfix for choosing the more specialized overload

There was a bug in clang where it couldn't choose which overload candidate is
more specialized if it was comparing a member-function to a non-member
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template
transformation described in [temp.func.order] paragraph 3 from
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the
transformed parameter list during the whole comperrassion. Also, to be able
to add the correct type for the implicit object parameter
Sema::getMoreSpecializedTemplate has new parameters for the object type.
---
 clang/include/clang/Sema/Sema.h  |   4 +-
 clang/lib/Sema/SemaOverload.cpp  |  12 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp | 263 +++
 3 files changed, 186 insertions(+), 93 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ef4b93fac95ce5..1a2a3a6bebd95e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9463,7 +9463,9 @@ class Sema final {
   FunctionTemplateDecl *getMoreSpecializedTemplate(
   FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
   TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-  unsigned NumCallArguments2, bool Reversed = false);
+  unsigned NumCallArguments2, QualType ObjType1 = {},
+  QualType ObjType2 = {}, bool Reversed = false);
+
   UnresolvedSetIterator
   getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
  TemplateSpecCandidateSet &FailedCandidates,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d38043890ca20..60138236abf1d8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10526,14 +10526,24 @@ bool clang::isBetterOverloadCandidate(
   //  according to the partial ordering rules described in 14.5.5.2, or,
   //  if not that,
   if (Cand1IsSpecialization && Cand2IsSpecialization) {
+const auto *ObjContext1 =
+dyn_cast(Cand1.FoundDecl->getDeclContext());
+const auto *ObjContext2 =
+dyn_cast(Cand2.FoundDecl->getDeclContext());
 if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(
 Cand1.Function->getPrimaryTemplate(),
 Cand2.Function->getPrimaryTemplate(), Loc,
 isa(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
 Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments,
-Cand1.isReversed() ^ Cand2.isReversed()))
+ObjContext1 ? QualType(ObjContext1->getTypeForDecl(), 0)
+: QualType{},
+ObjContext2 ? QualType(ObjContext2->getTypeForDecl(), 0)
+: QualType{},
+Cand1.isReversed() ^ Cand2.isReversed())) {
   return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+}
+
   }
 
   //   -— F1 and F2 are non-template functions with the same
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 563491f76f5478..2af3c29ae1f1c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5333,11 +5333,31 @@ bool 
Sema::CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
   return false;
 }
 
+static QualType GetImplicitObjectParameterTypeCXX20(ASTContext &Context,
+const CXXMethodDecl 
*Method,
+QualType rawType,
+bool isOtherRvr) {
+  // C++20 [temp.func.order]p3.1, p3.2:
+  //- The type X(M ) is “rvalue reference to cv A” if the optional 
ref-qualifier
+  //  of M is && or if M has no ref-qualifier and the 
positionally-corresponding
+  //  parameter of the other transformed template has rvalue reference type;
+  //  if this determination depends recursively upon whether X(M ) is an rvalue
+  //  reference type, it is not considered to have rvalue reference type.
+  //- Otherwise, X(M ) is “lvalue reference to cv A”.
+  assert(Method && !Method->isExplicitObjectMemberFunction() &&
+ "expected a member function with no explicit object parameter");
+
+  rawType = Context.getQualifiedType(rawType, Method->getMethodQualifiers());
+  if (Method->getRefQualifier() == RQ_RValue ||
+  (isOtherRvr && Method->getRefQualifier() == RQ_None))
+return Context.getRValueReferenceType(rawType);
+  return Context.getLValueReferenceTyp

[clang] [clang][Sema] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-06 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/83279

From 9ec2e0184be423223f6e5b5ba58c3a7224ae1b93 Mon Sep 17 00:00:00 2001
From: Botond Istvan Horvath 
Date: Wed, 28 Feb 2024 13:09:15 +0100
Subject: [PATCH 1/2] Bugfix for choosing the more specialized overload

There was a bug in clang where it couldn't choose which overload candidate is
more specialized if it was comparing a member-function to a non-member
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template
transformation described in [temp.func.order] paragraph 3 from
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the
transformed parameter list during the whole comperrassion. Also, to be able
to add the correct type for the implicit object parameter
Sema::getMoreSpecializedTemplate has new parameters for the object type.
---
 clang/docs/ReleaseNotes.rst|   6 +
 clang/include/clang/Sema/Sema.h|   3 +-
 clang/lib/Sema/SemaOverload.cpp|  13 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp   | 237 +++--
 clang/test/CXX/drs/dr24xx.cpp  |  61 ++
 clang/test/SemaCXX/overload-template.cpp   |  25 +++
 clang/test/SemaCXX/overloaded-operator.cpp |  37 
 clang/www/cxx_dr_status.html   |   2 +-
 8 files changed, 273 insertions(+), 111 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0ff4a93b15ea8f..942820a5268576 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -319,6 +319,12 @@ Bug Fixes to C++ Support
   Fixes (#GH80630)
 - Fix a crash when an explicit template argument list is used with a name for 
which lookup
   finds a non-template function and a dependent using declarator.
+- Fix a bug where overload resolution falsely reported an ambiguity when it 
was comparing
+  a member-function against a non member function or a member-function with an
+  explicit object parameter against a member function with no explicit object 
parameter
+  when one of the function had more specialized templates.
+  Fixes (`#82509 `_)
+  and (`#74494 `_)
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f3d3a57104ee07..2d949f3fc9a718 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9952,7 +9952,8 @@ class Sema final {
   FunctionTemplateDecl *getMoreSpecializedTemplate(
   FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
   TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-  unsigned NumCallArguments2, bool Reversed = false);
+  QualType RawObj1Ty = {}, QualType RawObj2Ty = {}, bool Reversed = false);
+
   UnresolvedSetIterator
   getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
  TemplateSpecCandidateSet &FailedCandidates,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index a03f3eae5478eb..b0c693f078efe2 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10571,14 +10571,23 @@ bool clang::isBetterOverloadCandidate(
   //  according to the partial ordering rules described in 14.5.5.2, or,
   //  if not that,
   if (Cand1IsSpecialization && Cand2IsSpecialization) {
+const auto *Obj1Context =
+dyn_cast(Cand1.FoundDecl->getDeclContext());
+const auto *Obj2Context =
+dyn_cast(Cand2.FoundDecl->getDeclContext());
 if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(
 Cand1.Function->getPrimaryTemplate(),
 Cand2.Function->getPrimaryTemplate(), Loc,
 isa(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
-Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments,
-Cand1.isReversed() ^ Cand2.isReversed()))
+Cand1.ExplicitCallArguments,
+Obj1Context ? QualType(Obj1Context->getTypeForDecl(), 0)
+: QualType{},
+Obj2Context ? QualType(Obj2Context->getTypeForDecl(), 0)
+: QualType{},
+Cand1.isReversed() ^ Cand2.isReversed())) {
   return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+}
   }
 
   //   -— F1 and F2 are non-template functions with the same
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 563491f76f5478..f14861640f549a 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5333,38 +5333,37 @@ bool 
Sema::CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
   return false;
 }
 
-/// If

[clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-28 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs created 
https://github.com/llvm/llvm-project/pull/83279

There was a bug in clang where it couldn't choose which overload candidate is 
more specialized if it was comparing a member-function to a non-member 
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template 
transformation described in [temp.func.order] paragraph 3 from 
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the 
transformed parameter list during the whole comperrassion. Also, to be able to 
add the correct type for the implicit object parameter 
Sema::getMoreSpecializedTemplate has new parameters for the object type.

Fixes #74494 and #82509

From 68200ecf3267d1b3940fa73c25c50ee706932a98 Mon Sep 17 00:00:00 2001
From: Botond Istvan Horvath 
Date: Wed, 28 Feb 2024 13:09:15 +0100
Subject: [PATCH] Bugfix for choosing the more specialized overload

There was a bug in clang where it couldn't choose which overload candidate is
more specialized if it was comparing a member-function to a non-member
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template
transformation described in [temp.func.order] paragraph 3 from
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the
transformed parameter list during the whole comperrassion. Also, to be able
to add the correct type for the implicit object parameter
Sema::getMoreSpecializedTemplate has new parameters for the object type.
---
 clang/include/clang/Sema/Sema.h  |   4 +-
 clang/lib/Sema/SemaOverload.cpp  |  12 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp | 263 +++
 3 files changed, 186 insertions(+), 93 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ef4b93fac95ce5..1a2a3a6bebd95e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9463,7 +9463,9 @@ class Sema final {
   FunctionTemplateDecl *getMoreSpecializedTemplate(
   FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
   TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-  unsigned NumCallArguments2, bool Reversed = false);
+  unsigned NumCallArguments2, QualType ObjType1 = {},
+  QualType ObjType2 = {}, bool Reversed = false);
+
   UnresolvedSetIterator
   getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
  TemplateSpecCandidateSet &FailedCandidates,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d38043890ca20..60138236abf1d8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10526,14 +10526,24 @@ bool clang::isBetterOverloadCandidate(
   //  according to the partial ordering rules described in 14.5.5.2, or,
   //  if not that,
   if (Cand1IsSpecialization && Cand2IsSpecialization) {
+const auto *ObjContext1 =
+dyn_cast(Cand1.FoundDecl->getDeclContext());
+const auto *ObjContext2 =
+dyn_cast(Cand2.FoundDecl->getDeclContext());
 if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(
 Cand1.Function->getPrimaryTemplate(),
 Cand2.Function->getPrimaryTemplate(), Loc,
 isa(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
 Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments,
-Cand1.isReversed() ^ Cand2.isReversed()))
+ObjContext1 ? QualType(ObjContext1->getTypeForDecl(), 0)
+: QualType{},
+ObjContext2 ? QualType(ObjContext2->getTypeForDecl(), 0)
+: QualType{},
+Cand1.isReversed() ^ Cand2.isReversed())) {
   return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+}
+
   }
 
   //   -— F1 and F2 are non-template functions with the same
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 563491f76f5478..2af3c29ae1f1c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5333,11 +5333,31 @@ bool 
Sema::CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
   return false;
 }
 
+static QualType GetImplicitObjectParameterTypeCXX20(ASTContext &Context,
+const CXXMethodDecl 
*Method,
+QualType rawType,
+bool isOtherRvr) {
+  // C++20 [temp.func.order]p3.1, p3.2:
+  //- The type X(M ) is “rvalue reference to cv A” if the optional 
ref-qualifier
+  //  of M is && or if M has no ref-qualifier and the 
positionally-corresponding
+  //  parameter of th

[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-28 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs edited https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-28 Thread Botond István Horváth via cfe-commits

HoBoIs wrote:

@zygoloid @erichkeane Could you take a look?

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-28 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/83279

From 68200ecf3267d1b3940fa73c25c50ee706932a98 Mon Sep 17 00:00:00 2001
From: Botond Istvan Horvath 
Date: Wed, 28 Feb 2024 13:09:15 +0100
Subject: [PATCH 1/2] Bugfix for choosing the more specialized overload

There was a bug in clang where it couldn't choose which overload candidate is
more specialized if it was comparing a member-function to a non-member
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template
transformation described in [temp.func.order] paragraph 3 from
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the
transformed parameter list during the whole comperrassion. Also, to be able
to add the correct type for the implicit object parameter
Sema::getMoreSpecializedTemplate has new parameters for the object type.
---
 clang/include/clang/Sema/Sema.h  |   4 +-
 clang/lib/Sema/SemaOverload.cpp  |  12 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp | 263 +++
 3 files changed, 186 insertions(+), 93 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ef4b93fac95ce5..1a2a3a6bebd95e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9463,7 +9463,9 @@ class Sema final {
   FunctionTemplateDecl *getMoreSpecializedTemplate(
   FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
   TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-  unsigned NumCallArguments2, bool Reversed = false);
+  unsigned NumCallArguments2, QualType ObjType1 = {},
+  QualType ObjType2 = {}, bool Reversed = false);
+
   UnresolvedSetIterator
   getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
  TemplateSpecCandidateSet &FailedCandidates,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d38043890ca20..60138236abf1d8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10526,14 +10526,24 @@ bool clang::isBetterOverloadCandidate(
   //  according to the partial ordering rules described in 14.5.5.2, or,
   //  if not that,
   if (Cand1IsSpecialization && Cand2IsSpecialization) {
+const auto *ObjContext1 =
+dyn_cast(Cand1.FoundDecl->getDeclContext());
+const auto *ObjContext2 =
+dyn_cast(Cand2.FoundDecl->getDeclContext());
 if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(
 Cand1.Function->getPrimaryTemplate(),
 Cand2.Function->getPrimaryTemplate(), Loc,
 isa(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
 Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments,
-Cand1.isReversed() ^ Cand2.isReversed()))
+ObjContext1 ? QualType(ObjContext1->getTypeForDecl(), 0)
+: QualType{},
+ObjContext2 ? QualType(ObjContext2->getTypeForDecl(), 0)
+: QualType{},
+Cand1.isReversed() ^ Cand2.isReversed())) {
   return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+}
+
   }
 
   //   -— F1 and F2 are non-template functions with the same
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 563491f76f5478..2af3c29ae1f1c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5333,11 +5333,31 @@ bool 
Sema::CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
   return false;
 }
 
+static QualType GetImplicitObjectParameterTypeCXX20(ASTContext &Context,
+const CXXMethodDecl 
*Method,
+QualType rawType,
+bool isOtherRvr) {
+  // C++20 [temp.func.order]p3.1, p3.2:
+  //- The type X(M ) is “rvalue reference to cv A” if the optional 
ref-qualifier
+  //  of M is && or if M has no ref-qualifier and the 
positionally-corresponding
+  //  parameter of the other transformed template has rvalue reference type;
+  //  if this determination depends recursively upon whether X(M ) is an rvalue
+  //  reference type, it is not considered to have rvalue reference type.
+  //- Otherwise, X(M ) is “lvalue reference to cv A”.
+  assert(Method && !Method->isExplicitObjectMemberFunction() &&
+ "expected a member function with no explicit object parameter");
+
+  rawType = Context.getQualifiedType(rawType, Method->getMethodQualifiers());
+  if (Method->getRefQualifier() == RQ_RValue ||
+  (isOtherRvr && Method->getRefQualifier() == RQ_None))
+return Context.getRValueReferenceType(rawType);
+  return Context.getLValueReferenceType(

[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-28 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/83279

From 68200ecf3267d1b3940fa73c25c50ee706932a98 Mon Sep 17 00:00:00 2001
From: Botond Istvan Horvath 
Date: Wed, 28 Feb 2024 13:09:15 +0100
Subject: [PATCH 1/3] Bugfix for choosing the more specialized overload

There was a bug in clang where it couldn't choose which overload candidate is
more specialized if it was comparing a member-function to a non-member
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template
transformation described in [temp.func.order] paragraph 3 from
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the
transformed parameter list during the whole comperrassion. Also, to be able
to add the correct type for the implicit object parameter
Sema::getMoreSpecializedTemplate has new parameters for the object type.
---
 clang/include/clang/Sema/Sema.h  |   4 +-
 clang/lib/Sema/SemaOverload.cpp  |  12 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp | 263 +++
 3 files changed, 186 insertions(+), 93 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ef4b93fac95ce5..1a2a3a6bebd95e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9463,7 +9463,9 @@ class Sema final {
   FunctionTemplateDecl *getMoreSpecializedTemplate(
   FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
   TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-  unsigned NumCallArguments2, bool Reversed = false);
+  unsigned NumCallArguments2, QualType ObjType1 = {},
+  QualType ObjType2 = {}, bool Reversed = false);
+
   UnresolvedSetIterator
   getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
  TemplateSpecCandidateSet &FailedCandidates,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d38043890ca20..60138236abf1d8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10526,14 +10526,24 @@ bool clang::isBetterOverloadCandidate(
   //  according to the partial ordering rules described in 14.5.5.2, or,
   //  if not that,
   if (Cand1IsSpecialization && Cand2IsSpecialization) {
+const auto *ObjContext1 =
+dyn_cast(Cand1.FoundDecl->getDeclContext());
+const auto *ObjContext2 =
+dyn_cast(Cand2.FoundDecl->getDeclContext());
 if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(
 Cand1.Function->getPrimaryTemplate(),
 Cand2.Function->getPrimaryTemplate(), Loc,
 isa(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
 Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments,
-Cand1.isReversed() ^ Cand2.isReversed()))
+ObjContext1 ? QualType(ObjContext1->getTypeForDecl(), 0)
+: QualType{},
+ObjContext2 ? QualType(ObjContext2->getTypeForDecl(), 0)
+: QualType{},
+Cand1.isReversed() ^ Cand2.isReversed())) {
   return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+}
+
   }
 
   //   -— F1 and F2 are non-template functions with the same
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 563491f76f5478..2af3c29ae1f1c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5333,11 +5333,31 @@ bool 
Sema::CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
   return false;
 }
 
+static QualType GetImplicitObjectParameterTypeCXX20(ASTContext &Context,
+const CXXMethodDecl 
*Method,
+QualType rawType,
+bool isOtherRvr) {
+  // C++20 [temp.func.order]p3.1, p3.2:
+  //- The type X(M ) is “rvalue reference to cv A” if the optional 
ref-qualifier
+  //  of M is && or if M has no ref-qualifier and the 
positionally-corresponding
+  //  parameter of the other transformed template has rvalue reference type;
+  //  if this determination depends recursively upon whether X(M ) is an rvalue
+  //  reference type, it is not considered to have rvalue reference type.
+  //- Otherwise, X(M ) is “lvalue reference to cv A”.
+  assert(Method && !Method->isExplicitObjectMemberFunction() &&
+ "expected a member function with no explicit object parameter");
+
+  rawType = Context.getQualifiedType(rawType, Method->getMethodQualifiers());
+  if (Method->getRefQualifier() == RQ_RValue ||
+  (isOtherRvr && Method->getRefQualifier() == RQ_None))
+return Context.getRValueReferenceType(rawType);
+  return Context.getLValueReferenceType(

[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-29 Thread Botond István Horváth via cfe-commits


@@ -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 Args1;
+  SmallVector 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();
+const FunctionProtoType *Proto2 =
+FD2->getType()->getAs();
+
+//   - In the context of a function call, the function parameter types are
+// used.
+const CXXMethodDecl *Method1 = dyn_cast(FD1);
+const CXXMethodDecl *Method2 = dyn_cast(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
+   ? Method2->getRefQualifier() == RQ_RValue
+   : Proto2->param_type_begin()[0]->isRValueReferenceType());
+  // Compare 'this' from Method1 against first parameter from Method2.
+  ObjType1 = GetImplicitObjectParameterType(this->Context, Method1,
+RawObjType1, isR2);
+  Args1.push_back(ObjType1);
+}
+if (shouldConvert2) {
+  bool isR1 =
+  getLangOpts().CPlusPlus20 &&
+  (shouldConvert2
+   ? Method1->getRefQualifier() == RQ_RValue
+   : Proto1->param_type_begin()[0]->isRValueReferenceType());
+  // Compare 'this' from Method2 against first parameter from Method1.
+  ObjType2 = GetImplicitObjectParameterType(this->Context, Method2,
+RawObjType2, isR1);
+  Args2.push_back(ObjType2);
+}
+unsigned NumComparedArguments = NumCallArguments1 + shouldConvert1;
 
-  bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC,
-  NumCallArguments1, Reversed);
-  bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC,
-  NumCallArguments2, Reversed);
+Args1.insert(Args1.end(), Proto1->param_type_begin(),
+ Proto1->param_type_end());
+Args2.insert(Args2.end(), Proto2->param_type_begin(),
+ Proto2->param_type_end());
 
+// C++ [temp.func.order]p5:
+//   The presence of unused ellipsis and default arguments has no effect on
+//   the partial ordering of function templates.
+if (Args1.size() > NumComparedArguments)

HoBoIs wrote:

   `Args1.resize(std::max(Args1.size(), NumComparedArguments));` is not 
functionally equivalent to what I wrote, and will not work as intended. I need 
to drop elements, not to add new default constructed ones. I think you meant to 
write `min` instead of `max`. 
 Still I don't see why `Args1.resize(min(Args1.size(), NumComparedArguments));` 
is preferable to the original.

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits m

[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-29 Thread Botond István Horváth via cfe-commits


@@ -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 Args1;
+  SmallVector 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();
+const FunctionProtoType *Proto2 =
+FD2->getType()->getAs();
+
+//   - In the context of a function call, the function parameter types are
+// used.
+const CXXMethodDecl *Method1 = dyn_cast(FD1);
+const CXXMethodDecl *Method2 = dyn_cast(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

HoBoIs wrote:

Actually I just mixed up `shouldConvert1` and `shouldConvert2`

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-29 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/83279

From 68200ecf3267d1b3940fa73c25c50ee706932a98 Mon Sep 17 00:00:00 2001
From: Botond Istvan Horvath 
Date: Wed, 28 Feb 2024 13:09:15 +0100
Subject: [PATCH 1/4] Bugfix for choosing the more specialized overload

There was a bug in clang where it couldn't choose which overload candidate is
more specialized if it was comparing a member-function to a non-member
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template
transformation described in [temp.func.order] paragraph 3 from
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the
transformed parameter list during the whole comperrassion. Also, to be able
to add the correct type for the implicit object parameter
Sema::getMoreSpecializedTemplate has new parameters for the object type.
---
 clang/include/clang/Sema/Sema.h  |   4 +-
 clang/lib/Sema/SemaOverload.cpp  |  12 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp | 263 +++
 3 files changed, 186 insertions(+), 93 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ef4b93fac95ce5..1a2a3a6bebd95e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9463,7 +9463,9 @@ class Sema final {
   FunctionTemplateDecl *getMoreSpecializedTemplate(
   FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
   TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-  unsigned NumCallArguments2, bool Reversed = false);
+  unsigned NumCallArguments2, QualType ObjType1 = {},
+  QualType ObjType2 = {}, bool Reversed = false);
+
   UnresolvedSetIterator
   getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
  TemplateSpecCandidateSet &FailedCandidates,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d38043890ca20..60138236abf1d8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10526,14 +10526,24 @@ bool clang::isBetterOverloadCandidate(
   //  according to the partial ordering rules described in 14.5.5.2, or,
   //  if not that,
   if (Cand1IsSpecialization && Cand2IsSpecialization) {
+const auto *ObjContext1 =
+dyn_cast(Cand1.FoundDecl->getDeclContext());
+const auto *ObjContext2 =
+dyn_cast(Cand2.FoundDecl->getDeclContext());
 if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(
 Cand1.Function->getPrimaryTemplate(),
 Cand2.Function->getPrimaryTemplate(), Loc,
 isa(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
 Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments,
-Cand1.isReversed() ^ Cand2.isReversed()))
+ObjContext1 ? QualType(ObjContext1->getTypeForDecl(), 0)
+: QualType{},
+ObjContext2 ? QualType(ObjContext2->getTypeForDecl(), 0)
+: QualType{},
+Cand1.isReversed() ^ Cand2.isReversed())) {
   return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+}
+
   }
 
   //   -— F1 and F2 are non-template functions with the same
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 563491f76f5478..2af3c29ae1f1c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5333,11 +5333,31 @@ bool 
Sema::CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
   return false;
 }
 
+static QualType GetImplicitObjectParameterTypeCXX20(ASTContext &Context,
+const CXXMethodDecl 
*Method,
+QualType rawType,
+bool isOtherRvr) {
+  // C++20 [temp.func.order]p3.1, p3.2:
+  //- The type X(M ) is “rvalue reference to cv A” if the optional 
ref-qualifier
+  //  of M is && or if M has no ref-qualifier and the 
positionally-corresponding
+  //  parameter of the other transformed template has rvalue reference type;
+  //  if this determination depends recursively upon whether X(M ) is an rvalue
+  //  reference type, it is not considered to have rvalue reference type.
+  //- Otherwise, X(M ) is “lvalue reference to cv A”.
+  assert(Method && !Method->isExplicitObjectMemberFunction() &&
+ "expected a member function with no explicit object parameter");
+
+  rawType = Context.getQualifiedType(rawType, Method->getMethodQualifiers());
+  if (Method->getRefQualifier() == RQ_RValue ||
+  (isOtherRvr && Method->getRefQualifier() == RQ_None))
+return Context.getRValueReferenceType(rawType);
+  return Context.getLValueReferenceType(

[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-29 Thread Botond István Horváth via cfe-commits


@@ -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 Args1;
+  SmallVector 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();
+const FunctionProtoType *Proto2 =
+FD2->getType()->getAs();
+
+//   - In the context of a function call, the function parameter types are
+// used.
+const CXXMethodDecl *Method1 = dyn_cast(FD1);
+const CXXMethodDecl *Method2 = dyn_cast(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

HoBoIs wrote:

fixed


https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-01 Thread Botond István Horváth via cfe-commits


@@ -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 Args1;
+  SmallVector 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();
+const FunctionProtoType *Proto2 =
+FD2->getType()->getAs();
+
+//   - In the context of a function call, the function parameter types are
+// used.
+const CXXMethodDecl *Method1 = dyn_cast(FD1);
+const CXXMethodDecl *Method2 = dyn_cast(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
+   ? Method2->getRefQualifier() == RQ_RValue
+   : Proto2->param_type_begin()[0]->isRValueReferenceType());
+  // Compare 'this' from Method1 against first parameter from Method2.
+  ObjType1 = GetImplicitObjectParameterType(this->Context, Method1,
+RawObjType1, isR2);
+  Args1.push_back(ObjType1);
+}
+if (shouldConvert2) {
+  bool isR1 =
+  getLangOpts().CPlusPlus20 &&
+  (shouldConvert2
+   ? Method1->getRefQualifier() == RQ_RValue
+   : Proto1->param_type_begin()[0]->isRValueReferenceType());
+  // Compare 'this' from Method2 against first parameter from Method1.
+  ObjType2 = GetImplicitObjectParameterType(this->Context, Method2,
+RawObjType2, isR1);
+  Args2.push_back(ObjType2);
+}
+unsigned NumComparedArguments = NumCallArguments1 + shouldConvert1;
 
-  bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC,
-  NumCallArguments1, Reversed);
-  bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC,
-  NumCallArguments2, Reversed);
+Args1.insert(Args1.end(), Proto1->param_type_begin(),
+ Proto1->param_type_end());
+Args2.insert(Args2.end(), Proto2->param_type_begin(),
+ Proto2->param_type_end());
 
+// C++ [temp.func.order]p5:
+//   The presence of unused ellipsis and default arguments has no effect on
+//   the partial ordering of function templates.
+if (Args1.size() > NumComparedArguments)

HoBoIs wrote:

How can I make it less confusing? Should I put in a comment explaining that in 
`Args1` and `Args2` after the first `NumComparedArguments` elements there can 
only be unused ellipsis and default arguments? (It already states that  unused 
ellipsis and default arguments has no effect on the partial ordering of 
function templates. Just above the if)

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@li

[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-01 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/83279

From 68200ecf3267d1b3940fa73c25c50ee706932a98 Mon Sep 17 00:00:00 2001
From: Botond Istvan Horvath 
Date: Wed, 28 Feb 2024 13:09:15 +0100
Subject: [PATCH 1/5] Bugfix for choosing the more specialized overload

There was a bug in clang where it couldn't choose which overload candidate is
more specialized if it was comparing a member-function to a non-member
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template
transformation described in [temp.func.order] paragraph 3 from
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the
transformed parameter list during the whole comperrassion. Also, to be able
to add the correct type for the implicit object parameter
Sema::getMoreSpecializedTemplate has new parameters for the object type.
---
 clang/include/clang/Sema/Sema.h  |   4 +-
 clang/lib/Sema/SemaOverload.cpp  |  12 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp | 263 +++
 3 files changed, 186 insertions(+), 93 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ef4b93fac95ce5..1a2a3a6bebd95e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9463,7 +9463,9 @@ class Sema final {
   FunctionTemplateDecl *getMoreSpecializedTemplate(
   FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
   TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-  unsigned NumCallArguments2, bool Reversed = false);
+  unsigned NumCallArguments2, QualType ObjType1 = {},
+  QualType ObjType2 = {}, bool Reversed = false);
+
   UnresolvedSetIterator
   getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
  TemplateSpecCandidateSet &FailedCandidates,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d38043890ca20..60138236abf1d8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10526,14 +10526,24 @@ bool clang::isBetterOverloadCandidate(
   //  according to the partial ordering rules described in 14.5.5.2, or,
   //  if not that,
   if (Cand1IsSpecialization && Cand2IsSpecialization) {
+const auto *ObjContext1 =
+dyn_cast(Cand1.FoundDecl->getDeclContext());
+const auto *ObjContext2 =
+dyn_cast(Cand2.FoundDecl->getDeclContext());
 if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(
 Cand1.Function->getPrimaryTemplate(),
 Cand2.Function->getPrimaryTemplate(), Loc,
 isa(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
 Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments,
-Cand1.isReversed() ^ Cand2.isReversed()))
+ObjContext1 ? QualType(ObjContext1->getTypeForDecl(), 0)
+: QualType{},
+ObjContext2 ? QualType(ObjContext2->getTypeForDecl(), 0)
+: QualType{},
+Cand1.isReversed() ^ Cand2.isReversed())) {
   return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+}
+
   }
 
   //   -— F1 and F2 are non-template functions with the same
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 563491f76f5478..2af3c29ae1f1c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5333,11 +5333,31 @@ bool 
Sema::CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
   return false;
 }
 
+static QualType GetImplicitObjectParameterTypeCXX20(ASTContext &Context,
+const CXXMethodDecl 
*Method,
+QualType rawType,
+bool isOtherRvr) {
+  // C++20 [temp.func.order]p3.1, p3.2:
+  //- The type X(M ) is “rvalue reference to cv A” if the optional 
ref-qualifier
+  //  of M is && or if M has no ref-qualifier and the 
positionally-corresponding
+  //  parameter of the other transformed template has rvalue reference type;
+  //  if this determination depends recursively upon whether X(M ) is an rvalue
+  //  reference type, it is not considered to have rvalue reference type.
+  //- Otherwise, X(M ) is “lvalue reference to cv A”.
+  assert(Method && !Method->isExplicitObjectMemberFunction() &&
+ "expected a member function with no explicit object parameter");
+
+  rawType = Context.getQualifiedType(rawType, Method->getMethodQualifiers());
+  if (Method->getRefQualifier() == RQ_RValue ||
+  (isOtherRvr && Method->getRefQualifier() == RQ_None))
+return Context.getRValueReferenceType(rawType);
+  return Context.getLValueReferenceType(

[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-01 Thread Botond István Horváth via cfe-commits


@@ -14478,7 +14478,7 @@ C++ defect report implementation 
status
 https://cplusplus.github.io/CWG/issues/2445.html";>2445
 C++20
 Partial ordering with rewritten candidates
-Unknown
+Clang 18

HoBoIs wrote:

I'm on it. While we are at here: should it be `18` or `19` ? As I can see 18 is 
almost out.

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-01 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs edited https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-01 Thread Botond István Horváth via cfe-commits


@@ -14478,7 +14478,7 @@ C++ defect report implementation 
status
 https://cplusplus.github.io/CWG/issues/2445.html";>2445
 C++20
 Partial ordering with rewritten candidates
-Unknown
+Clang 18

HoBoIs wrote:

done

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-01 Thread Botond István Horváth via cfe-commits

HoBoIs wrote:

> DR changes looks good now, save for a nitpick. However, I'm leaving it to 
> other reviewers to check contents of the test. It looks like an example from 
> the DR, but I don't feel qualified to say whether this test has sufficient 
> coverage.

I have added tests to other files what are relevant for the DR too. Should I 
move them here?

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-04 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/83279

From 68200ecf3267d1b3940fa73c25c50ee706932a98 Mon Sep 17 00:00:00 2001
From: Botond Istvan Horvath 
Date: Wed, 28 Feb 2024 13:09:15 +0100
Subject: [PATCH 1/7] Bugfix for choosing the more specialized overload

There was a bug in clang where it couldn't choose which overload candidate is
more specialized if it was comparing a member-function to a non-member
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template
transformation described in [temp.func.order] paragraph 3 from
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the
transformed parameter list during the whole comperrassion. Also, to be able
to add the correct type for the implicit object parameter
Sema::getMoreSpecializedTemplate has new parameters for the object type.
---
 clang/include/clang/Sema/Sema.h  |   4 +-
 clang/lib/Sema/SemaOverload.cpp  |  12 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp | 263 +++
 3 files changed, 186 insertions(+), 93 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ef4b93fac95ce5..1a2a3a6bebd95e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9463,7 +9463,9 @@ class Sema final {
   FunctionTemplateDecl *getMoreSpecializedTemplate(
   FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
   TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-  unsigned NumCallArguments2, bool Reversed = false);
+  unsigned NumCallArguments2, QualType ObjType1 = {},
+  QualType ObjType2 = {}, bool Reversed = false);
+
   UnresolvedSetIterator
   getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
  TemplateSpecCandidateSet &FailedCandidates,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d38043890ca20..60138236abf1d8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10526,14 +10526,24 @@ bool clang::isBetterOverloadCandidate(
   //  according to the partial ordering rules described in 14.5.5.2, or,
   //  if not that,
   if (Cand1IsSpecialization && Cand2IsSpecialization) {
+const auto *ObjContext1 =
+dyn_cast(Cand1.FoundDecl->getDeclContext());
+const auto *ObjContext2 =
+dyn_cast(Cand2.FoundDecl->getDeclContext());
 if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(
 Cand1.Function->getPrimaryTemplate(),
 Cand2.Function->getPrimaryTemplate(), Loc,
 isa(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
 Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments,
-Cand1.isReversed() ^ Cand2.isReversed()))
+ObjContext1 ? QualType(ObjContext1->getTypeForDecl(), 0)
+: QualType{},
+ObjContext2 ? QualType(ObjContext2->getTypeForDecl(), 0)
+: QualType{},
+Cand1.isReversed() ^ Cand2.isReversed())) {
   return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+}
+
   }
 
   //   -— F1 and F2 are non-template functions with the same
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 563491f76f5478..2af3c29ae1f1c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5333,11 +5333,31 @@ bool 
Sema::CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
   return false;
 }
 
+static QualType GetImplicitObjectParameterTypeCXX20(ASTContext &Context,
+const CXXMethodDecl 
*Method,
+QualType rawType,
+bool isOtherRvr) {
+  // C++20 [temp.func.order]p3.1, p3.2:
+  //- The type X(M ) is “rvalue reference to cv A” if the optional 
ref-qualifier
+  //  of M is && or if M has no ref-qualifier and the 
positionally-corresponding
+  //  parameter of the other transformed template has rvalue reference type;
+  //  if this determination depends recursively upon whether X(M ) is an rvalue
+  //  reference type, it is not considered to have rvalue reference type.
+  //- Otherwise, X(M ) is “lvalue reference to cv A”.
+  assert(Method && !Method->isExplicitObjectMemberFunction() &&
+ "expected a member function with no explicit object parameter");
+
+  rawType = Context.getQualifiedType(rawType, Method->getMethodQualifiers());
+  if (Method->getRefQualifier() == RQ_RValue ||
+  (isOtherRvr && Method->getRefQualifier() == RQ_None))
+return Context.getRValueReferenceType(rawType);
+  return Context.getLValueReferenceType(

[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-04 Thread Botond István Horváth via cfe-commits


@@ -68,3 +68,35 @@ template struct X {};
 X<1> x;
 #endif
 }
+namespace dr2445 { // dr2445: 19

HoBoIs wrote:

done

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-04 Thread Botond István Horváth via cfe-commits

HoBoIs wrote:

I have added tests for rvalref-s and `volatile`-s.

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-05 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/83279

From 68200ecf3267d1b3940fa73c25c50ee706932a98 Mon Sep 17 00:00:00 2001
From: Botond Istvan Horvath 
Date: Wed, 28 Feb 2024 13:09:15 +0100
Subject: [PATCH 1/8] Bugfix for choosing the more specialized overload

There was a bug in clang where it couldn't choose which overload candidate is
more specialized if it was comparing a member-function to a non-member
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template
transformation described in [temp.func.order] paragraph 3 from
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the
transformed parameter list during the whole comperrassion. Also, to be able
to add the correct type for the implicit object parameter
Sema::getMoreSpecializedTemplate has new parameters for the object type.
---
 clang/include/clang/Sema/Sema.h  |   4 +-
 clang/lib/Sema/SemaOverload.cpp  |  12 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp | 263 +++
 3 files changed, 186 insertions(+), 93 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ef4b93fac95ce5..1a2a3a6bebd95e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9463,7 +9463,9 @@ class Sema final {
   FunctionTemplateDecl *getMoreSpecializedTemplate(
   FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
   TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-  unsigned NumCallArguments2, bool Reversed = false);
+  unsigned NumCallArguments2, QualType ObjType1 = {},
+  QualType ObjType2 = {}, bool Reversed = false);
+
   UnresolvedSetIterator
   getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
  TemplateSpecCandidateSet &FailedCandidates,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d38043890ca20..60138236abf1d8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10526,14 +10526,24 @@ bool clang::isBetterOverloadCandidate(
   //  according to the partial ordering rules described in 14.5.5.2, or,
   //  if not that,
   if (Cand1IsSpecialization && Cand2IsSpecialization) {
+const auto *ObjContext1 =
+dyn_cast(Cand1.FoundDecl->getDeclContext());
+const auto *ObjContext2 =
+dyn_cast(Cand2.FoundDecl->getDeclContext());
 if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(
 Cand1.Function->getPrimaryTemplate(),
 Cand2.Function->getPrimaryTemplate(), Loc,
 isa(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
 Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments,
-Cand1.isReversed() ^ Cand2.isReversed()))
+ObjContext1 ? QualType(ObjContext1->getTypeForDecl(), 0)
+: QualType{},
+ObjContext2 ? QualType(ObjContext2->getTypeForDecl(), 0)
+: QualType{},
+Cand1.isReversed() ^ Cand2.isReversed())) {
   return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+}
+
   }
 
   //   -— F1 and F2 are non-template functions with the same
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 563491f76f5478..2af3c29ae1f1c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5333,11 +5333,31 @@ bool 
Sema::CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
   return false;
 }
 
+static QualType GetImplicitObjectParameterTypeCXX20(ASTContext &Context,
+const CXXMethodDecl 
*Method,
+QualType rawType,
+bool isOtherRvr) {
+  // C++20 [temp.func.order]p3.1, p3.2:
+  //- The type X(M ) is “rvalue reference to cv A” if the optional 
ref-qualifier
+  //  of M is && or if M has no ref-qualifier and the 
positionally-corresponding
+  //  parameter of the other transformed template has rvalue reference type;
+  //  if this determination depends recursively upon whether X(M ) is an rvalue
+  //  reference type, it is not considered to have rvalue reference type.
+  //- Otherwise, X(M ) is “lvalue reference to cv A”.
+  assert(Method && !Method->isExplicitObjectMemberFunction() &&
+ "expected a member function with no explicit object parameter");
+
+  rawType = Context.getQualifiedType(rawType, Method->getMethodQualifiers());
+  if (Method->getRefQualifier() == RQ_RValue ||
+  (isOtherRvr && Method->getRefQualifier() == RQ_None))
+return Context.getRValueReferenceType(rawType);
+  return Context.getLValueReferenceType(

[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-05 Thread Botond István Horváth via cfe-commits

HoBoIs wrote:

@erichkeane a question: this PR is partly a fix for a DR for c++20. Right now I 
only apply the fix for C++20 and newer. Is there a reason for not applying this 
fix for older standards? I don't see how it would break any existing code, and 
making the fix retroactive doesn't make any test fail.

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-05 Thread Botond István Horváth via cfe-commits

HoBoIs wrote:

> I don't think checking for c++20 is useful because rewritten candidates are a 
> c++20- feature anyway

Yes, but the resolution of the DR also talks about the reference type of the 
object parameter. (If I apply the patch retroactively the code will get 
simpler.)

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-03-05 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/83279

From 68200ecf3267d1b3940fa73c25c50ee706932a98 Mon Sep 17 00:00:00 2001
From: Botond Istvan Horvath 
Date: Wed, 28 Feb 2024 13:09:15 +0100
Subject: [PATCH 1/9] Bugfix for choosing the more specialized overload

There was a bug in clang where it couldn't choose which overload candidate is
more specialized if it was comparing a member-function to a non-member
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template
transformation described in [temp.func.order] paragraph 3 from
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the
transformed parameter list during the whole comperrassion. Also, to be able
to add the correct type for the implicit object parameter
Sema::getMoreSpecializedTemplate has new parameters for the object type.
---
 clang/include/clang/Sema/Sema.h  |   4 +-
 clang/lib/Sema/SemaOverload.cpp  |  12 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp | 263 +++
 3 files changed, 186 insertions(+), 93 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ef4b93fac95ce5..1a2a3a6bebd95e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9463,7 +9463,9 @@ class Sema final {
   FunctionTemplateDecl *getMoreSpecializedTemplate(
   FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
   TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-  unsigned NumCallArguments2, bool Reversed = false);
+  unsigned NumCallArguments2, QualType ObjType1 = {},
+  QualType ObjType2 = {}, bool Reversed = false);
+
   UnresolvedSetIterator
   getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
  TemplateSpecCandidateSet &FailedCandidates,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d38043890ca20..60138236abf1d8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10526,14 +10526,24 @@ bool clang::isBetterOverloadCandidate(
   //  according to the partial ordering rules described in 14.5.5.2, or,
   //  if not that,
   if (Cand1IsSpecialization && Cand2IsSpecialization) {
+const auto *ObjContext1 =
+dyn_cast(Cand1.FoundDecl->getDeclContext());
+const auto *ObjContext2 =
+dyn_cast(Cand2.FoundDecl->getDeclContext());
 if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(
 Cand1.Function->getPrimaryTemplate(),
 Cand2.Function->getPrimaryTemplate(), Loc,
 isa(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
 Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments,
-Cand1.isReversed() ^ Cand2.isReversed()))
+ObjContext1 ? QualType(ObjContext1->getTypeForDecl(), 0)
+: QualType{},
+ObjContext2 ? QualType(ObjContext2->getTypeForDecl(), 0)
+: QualType{},
+Cand1.isReversed() ^ Cand2.isReversed())) {
   return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+}
+
   }
 
   //   -— F1 and F2 are non-template functions with the same
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 563491f76f5478..2af3c29ae1f1c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5333,11 +5333,31 @@ bool 
Sema::CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
   return false;
 }
 
+static QualType GetImplicitObjectParameterTypeCXX20(ASTContext &Context,
+const CXXMethodDecl 
*Method,
+QualType rawType,
+bool isOtherRvr) {
+  // C++20 [temp.func.order]p3.1, p3.2:
+  //- The type X(M ) is “rvalue reference to cv A” if the optional 
ref-qualifier
+  //  of M is && or if M has no ref-qualifier and the 
positionally-corresponding
+  //  parameter of the other transformed template has rvalue reference type;
+  //  if this determination depends recursively upon whether X(M ) is an rvalue
+  //  reference type, it is not considered to have rvalue reference type.
+  //- Otherwise, X(M ) is “lvalue reference to cv A”.
+  assert(Method && !Method->isExplicitObjectMemberFunction() &&
+ "expected a member function with no explicit object parameter");
+
+  rawType = Context.getQualifiedType(rawType, Method->getMethodQualifiers());
+  if (Method->getRefQualifier() == RQ_RValue ||
+  (isOtherRvr && Method->getRefQualifier() == RQ_None))
+return Context.getRValueReferenceType(rawType);
+  return Context.getLValueReferenceType(

[clang] Correct end for the CastOperation.OpRange (PR #69480)

2023-10-18 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs created 
https://github.com/llvm/llvm-project/pull/69480

Set the correct end for the CastOperation.OpRange in CXXFunctionalCastExpr. Now 
it is the closing bracket's location instead of the parameter's location.

This can lead to better highlight in the diagnostics. 
Similar to https://github.com/llvm/llvm-project/pull/66853
Example:
Before:
```
warning: cast from 'long (*)(const int &)' to 'decltype(fun_ptr)' (aka 'long 
(*)(int &)') converts to incompatible function type 
[-Wcast-function-type-strict]
   24 | return decltype(fun_ptr)( f_ptr /*comment*/);
  |^~~~
```
After:
```
warning: cast from 'long (*)(const int &)' to 'decltype(fun_ptr)' (aka 'long 
(*)(int &)') converts to incompatible function type 
[-Wcast-function-type-strict]
   24 | return decltype(fun_ptr)( f_ptr /*comment*/);
  |^
```

From f75c2e75042d6d8f5a093967a56f3f59d7e541f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Botond=20Istv=C3=A1n=20Horv=C3=A1th?=
 <56926027+hob...@users.noreply.github.com>
Date: Wed, 18 Oct 2023 18:05:01 +0200
Subject: [PATCH] Correct end for the CastOperation.OpRange

Set the correct end for the CastOperation.OpRange in CXXFunctionalCastExpr. Now 
it is the closing bracket's location instead of the parameter's location.
---
 clang/lib/Sema/SemaCast.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 98b5879456e2175..87e6d1a2198fcea 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -3362,7 +3362,7 @@ ExprResult 
Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
   assert(LPLoc.isValid() && "List-initialization shouldn't get here.");
   CastOperation Op(*this, Type, CastExpr);
   Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
-  Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getEndLoc());
+  Op.OpRange = SourceRange(Op.DestRange.getBegin(), RPLoc);
 
   Op.CheckCXXCStyleCast(/*FunctionalCast=*/true, /*ListInit=*/false);
   if (Op.SrcExpr.isInvalid())

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] Correct end for the CastOperation.OpRange (PR #69480)

2023-10-19 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/69480

From f75c2e75042d6d8f5a093967a56f3f59d7e541f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Botond=20Istv=C3=A1n=20Horv=C3=A1th?=
 <56926027+hob...@users.noreply.github.com>
Date: Wed, 18 Oct 2023 18:05:01 +0200
Subject: [PATCH 1/2] Correct end for the CastOperation.OpRange

Set the correct end for the CastOperation.OpRange in CXXFunctionalCastExpr. Now 
it is the closing bracket's location instead of the parameter's location.
---
 clang/lib/Sema/SemaCast.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 98b5879456e2175..87e6d1a2198fcea 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -3362,7 +3362,7 @@ ExprResult 
Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
   assert(LPLoc.isValid() && "List-initialization shouldn't get here.");
   CastOperation Op(*this, Type, CastExpr);
   Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
-  Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getEndLoc());
+  Op.OpRange = SourceRange(Op.DestRange.getBegin(), RPLoc);
 
   Op.CheckCXXCStyleCast(/*FunctionalCast=*/true, /*ListInit=*/false);
   if (Op.SrcExpr.isInvalid())

From c5b49768eaa4f4ceab110a9fc35a9fa0924409f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Botond=20Istv=C3=A1n=20Horv=C3=A1th?=
 <56926027+hob...@users.noreply.github.com>
Date: Thu, 19 Oct 2023 13:47:47 +0200
Subject: [PATCH 2/2] Added a test to misc-source-ranges.cpp

---
 clang/test/Misc/misc-source-ranges.cpp | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/clang/test/Misc/misc-source-ranges.cpp 
b/clang/test/Misc/misc-source-ranges.cpp
index 7a9d9d057dac407..5bc50f7a4281072 100644
--- a/clang/test/Misc/misc-source-ranges.cpp
+++ b/clang/test/Misc/misc-source-ranges.cpp
@@ -1,7 +1,13 @@
-// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info %s 
2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info 
-Wcast-function-type-strict %s 2>&1 | FileCheck %s
 
 struct S {
   char a : 12 - 12;
 };
 // CHECK: misc-source-ranges.cpp:[[@LINE-2]]:8:{[[@LINE-2]]:12-[[@LINE-2]]:19}
 
+using fun = long(*)(int&);
+fun foo(){
+  long (*f_ptr)(const int&);
+  return fun(f_ptr);
+}
+// CHECK: misc-source-ranges.cpp:[[@LINE-2]]:10:{[[@LINE-2]]:10-[[@LINE-2]]:20}

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Correct end for the `CastOperation.OpRange` (PR #69480)

2023-10-20 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/69480

From f75c2e75042d6d8f5a093967a56f3f59d7e541f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Botond=20Istv=C3=A1n=20Horv=C3=A1th?=
 <56926027+hob...@users.noreply.github.com>
Date: Wed, 18 Oct 2023 18:05:01 +0200
Subject: [PATCH 1/3] Correct end for the CastOperation.OpRange

Set the correct end for the CastOperation.OpRange in CXXFunctionalCastExpr. Now 
it is the closing bracket's location instead of the parameter's location.
---
 clang/lib/Sema/SemaCast.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 98b5879456e2175..87e6d1a2198fcea 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -3362,7 +3362,7 @@ ExprResult 
Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
   assert(LPLoc.isValid() && "List-initialization shouldn't get here.");
   CastOperation Op(*this, Type, CastExpr);
   Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
-  Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getEndLoc());
+  Op.OpRange = SourceRange(Op.DestRange.getBegin(), RPLoc);
 
   Op.CheckCXXCStyleCast(/*FunctionalCast=*/true, /*ListInit=*/false);
   if (Op.SrcExpr.isInvalid())

From c5b49768eaa4f4ceab110a9fc35a9fa0924409f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Botond=20Istv=C3=A1n=20Horv=C3=A1th?=
 <56926027+hob...@users.noreply.github.com>
Date: Thu, 19 Oct 2023 13:47:47 +0200
Subject: [PATCH 2/3] Added a test to misc-source-ranges.cpp

---
 clang/test/Misc/misc-source-ranges.cpp | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/clang/test/Misc/misc-source-ranges.cpp 
b/clang/test/Misc/misc-source-ranges.cpp
index 7a9d9d057dac407..5bc50f7a4281072 100644
--- a/clang/test/Misc/misc-source-ranges.cpp
+++ b/clang/test/Misc/misc-source-ranges.cpp
@@ -1,7 +1,13 @@
-// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info %s 
2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info 
-Wcast-function-type-strict %s 2>&1 | FileCheck %s
 
 struct S {
   char a : 12 - 12;
 };
 // CHECK: misc-source-ranges.cpp:[[@LINE-2]]:8:{[[@LINE-2]]:12-[[@LINE-2]]:19}
 
+using fun = long(*)(int&);
+fun foo(){
+  long (*f_ptr)(const int&);
+  return fun(f_ptr);
+}
+// CHECK: misc-source-ranges.cpp:[[@LINE-2]]:10:{[[@LINE-2]]:10-[[@LINE-2]]:20}

From bc65adadd2cb605b5655223a6781de746d534b2d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Botond=20Istv=C3=A1n=20Horv=C3=A1th?=
 <56926027+hob...@users.noreply.github.com>
Date: Fri, 20 Oct 2023 11:12:59 +0200
Subject: [PATCH 3/3] Update ReleaseNotes.rst

---
 clang/docs/ReleaseNotes.rst | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index eee48431d716878..4b67a5dce0945d3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -326,6 +326,25 @@ Improvements to Clang's diagnostics
 - Clang now always diagnoses when using non-standard layout types in 
``offsetof`` .
   (`#64619: `_)
 
+- When describing a warning/error in a function-style type converson clang 
underscored only until
+  the end of the expression we convert from. Now clang underscores the until 
the closing bracket.
+
+  Before:
+
+  .. code-block:: text
+
+warning: cast from 'long (*)(const int &)' to 'decltype(fun_ptr)' (aka 
'long (*)(int &)') converts to incompatible function type 
[-Wcast-function-type-strict]
+24 | return decltype(fun_ptr)( f_ptr /*comment*/);
+   |^~~~
+
+  After:
+
+  .. code-block:: text
+
+warning: cast from 'long (*)(const int &)' to 'decltype(fun_ptr)' (aka 
'long (*)(int &)') converts to incompatible function type 
[-Wcast-function-type-strict]
+24 | return decltype(fun_ptr)( f_ptr /*comment*/);
+   |^
+
 Bug Fixes in This Version
 -
 - Fixed an issue where a class template specialization whose declaration is

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang] Correct end for the `CastOperation.OpRange` (PR #69480)

2023-10-20 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/69480

From f75c2e75042d6d8f5a093967a56f3f59d7e541f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Botond=20Istv=C3=A1n=20Horv=C3=A1th?=
 <56926027+hob...@users.noreply.github.com>
Date: Wed, 18 Oct 2023 18:05:01 +0200
Subject: [PATCH 1/3] Correct end for the CastOperation.OpRange

Set the correct end for the CastOperation.OpRange in CXXFunctionalCastExpr. Now 
it is the closing bracket's location instead of the parameter's location.
---
 clang/lib/Sema/SemaCast.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 98b5879456e2175..87e6d1a2198fcea 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -3362,7 +3362,7 @@ ExprResult 
Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
   assert(LPLoc.isValid() && "List-initialization shouldn't get here.");
   CastOperation Op(*this, Type, CastExpr);
   Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
-  Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getEndLoc());
+  Op.OpRange = SourceRange(Op.DestRange.getBegin(), RPLoc);
 
   Op.CheckCXXCStyleCast(/*FunctionalCast=*/true, /*ListInit=*/false);
   if (Op.SrcExpr.isInvalid())

From c5b49768eaa4f4ceab110a9fc35a9fa0924409f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Botond=20Istv=C3=A1n=20Horv=C3=A1th?=
 <56926027+hob...@users.noreply.github.com>
Date: Thu, 19 Oct 2023 13:47:47 +0200
Subject: [PATCH 2/3] Added a test to misc-source-ranges.cpp

---
 clang/test/Misc/misc-source-ranges.cpp | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/clang/test/Misc/misc-source-ranges.cpp 
b/clang/test/Misc/misc-source-ranges.cpp
index 7a9d9d057dac407..5bc50f7a4281072 100644
--- a/clang/test/Misc/misc-source-ranges.cpp
+++ b/clang/test/Misc/misc-source-ranges.cpp
@@ -1,7 +1,13 @@
-// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info %s 
2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info 
-Wcast-function-type-strict %s 2>&1 | FileCheck %s
 
 struct S {
   char a : 12 - 12;
 };
 // CHECK: misc-source-ranges.cpp:[[@LINE-2]]:8:{[[@LINE-2]]:12-[[@LINE-2]]:19}
 
+using fun = long(*)(int&);
+fun foo(){
+  long (*f_ptr)(const int&);
+  return fun(f_ptr);
+}
+// CHECK: misc-source-ranges.cpp:[[@LINE-2]]:10:{[[@LINE-2]]:10-[[@LINE-2]]:20}

From bc65adadd2cb605b5655223a6781de746d534b2d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Botond=20Istv=C3=A1n=20Horv=C3=A1th?=
 <56926027+hob...@users.noreply.github.com>
Date: Fri, 20 Oct 2023 11:12:59 +0200
Subject: [PATCH 3/3] Update ReleaseNotes.rst

---
 clang/docs/ReleaseNotes.rst | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index eee48431d716878..4b67a5dce0945d3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -326,6 +326,25 @@ Improvements to Clang's diagnostics
 - Clang now always diagnoses when using non-standard layout types in 
``offsetof`` .
   (`#64619: `_)
 
+- When describing a warning/error in a function-style type converson clang 
underscored only until
+  the end of the expression we convert from. Now clang underscores the until 
the closing bracket.
+
+  Before:
+
+  .. code-block:: text
+
+warning: cast from 'long (*)(const int &)' to 'decltype(fun_ptr)' (aka 
'long (*)(int &)') converts to incompatible function type 
[-Wcast-function-type-strict]
+24 | return decltype(fun_ptr)( f_ptr /*comment*/);
+   |^~~~
+
+  After:
+
+  .. code-block:: text
+
+warning: cast from 'long (*)(const int &)' to 'decltype(fun_ptr)' (aka 
'long (*)(int &)') converts to incompatible function type 
[-Wcast-function-type-strict]
+24 | return decltype(fun_ptr)( f_ptr /*comment*/);
+   |^
+
 Bug Fixes in This Version
 -
 - Fixed an issue where a class template specialization whose declaration is

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Correct end for the `CastOperation.OpRange` (PR #69480)

2023-10-24 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/69480

From c06535386eb736fc11397cf11efaa8d52fdae4fd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Botond=20Istv=C3=A1n=20Horv=C3=A1th?=
 <56926027+hob...@users.noreply.github.com>
Date: Wed, 18 Oct 2023 18:05:01 +0200
Subject: [PATCH] Correct end for the CastOperation.OpRange

Set the correct end for the CastOperation.OpRange in CXXFunctionalCastExpr. Now 
it is the closing bracket's location instead of the parameter's location.
---
 clang/docs/ReleaseNotes.rst| 19 +++
 clang/lib/Sema/SemaCast.cpp|  2 +-
 clang/test/Misc/misc-source-ranges.cpp |  8 +++-
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4c24216888525cd..ae409d889cb0aa9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -379,6 +379,25 @@ Improvements to Clang's diagnostics
   can sometimes lead to worse ordering.
 
 
+- When describing a warning/error in a function-style type conversion Clang 
underlines only until
+  the end of the expression we convert from. Now Clang underlines until the 
closing parenthesis.
+
+  Before:
+
+  .. code-block:: text
+
+warning: cast from 'long (*)(const int &)' to 'decltype(fun_ptr)' (aka 
'long (*)(int &)') converts to incompatible function type 
[-Wcast-function-type-strict]
+24 | return decltype(fun_ptr)( f_ptr /*comment*/);
+   |^~~~
+
+  After:
+
+  .. code-block:: text
+
+warning: cast from 'long (*)(const int &)' to 'decltype(fun_ptr)' (aka 
'long (*)(int &)') converts to incompatible function type 
[-Wcast-function-type-strict]
+24 | return decltype(fun_ptr)( f_ptr /*comment*/);
+   |^
+
 Bug Fixes in This Version
 -
 - Fixed an issue where a class template specialization whose declaration is
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 98b5879456e2175..87e6d1a2198fcea 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -3362,7 +3362,7 @@ ExprResult 
Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
   assert(LPLoc.isValid() && "List-initialization shouldn't get here.");
   CastOperation Op(*this, Type, CastExpr);
   Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
-  Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getEndLoc());
+  Op.OpRange = SourceRange(Op.DestRange.getBegin(), RPLoc);
 
   Op.CheckCXXCStyleCast(/*FunctionalCast=*/true, /*ListInit=*/false);
   if (Op.SrcExpr.isInvalid())
diff --git a/clang/test/Misc/misc-source-ranges.cpp 
b/clang/test/Misc/misc-source-ranges.cpp
index 7a9d9d057dac407..1835952fd755902 100644
--- a/clang/test/Misc/misc-source-ranges.cpp
+++ b/clang/test/Misc/misc-source-ranges.cpp
@@ -1,7 +1,13 @@
-// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info %s 
2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info 
-Wcast-function-type-strict %s 2>&1 | FileCheck %s
 
 struct S {
   char a : 12 - 12;
 };
 // CHECK: misc-source-ranges.cpp:[[@LINE-2]]:8:{[[@LINE-2]]:12-[[@LINE-2]]:19}
 
+using fun = long(*)(int &);
+fun foo(){
+  long (*f_ptr)(const int &);
+  return fun(f_ptr);
+}
+// CHECK: misc-source-ranges.cpp:[[@LINE-2]]:10:{[[@LINE-2]]:10-[[@LINE-2]]:20}

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits