[clang] 3c75fea - [clang] Compare constraints before diagnosing mismatched ref qualifiers (GH58962)
Roy Jacobson via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 29 04:57:32 PST 2022
Author: Roy Jacobson
Date: 2022-11-29T14:57:26+02:00
New Revision: 3c75feab3bbda563374f08e46a7c052c0c6f1c36
URL: https://github.com/llvm/llvm-project/commit/3c75feab3bbda563374f08e46a7c052c0c6f1c36
DIFF: https://github.com/llvm/llvm-project/commit/3c75feab3bbda563374f08e46a7c052c0c6f1c36.diff
LOG: [clang] Compare constraints before diagnosing mismatched ref qualifiers (GH58962)
As noticed in GH58962, we should only diagnose illegal overloads of member functions
when the ref qualifiers don't match if the trailing constraints are the same.
The fix is to move the existing constraints check earlier in Sema::IsOverload.
Closes https://github.com/llvm/llvm-project/issues/58962
Reviewed By: erichkeane
Differential Revision: https://reviews.llvm.org/D138749
Added:
Modified:
clang/lib/Sema/SemaOverload.cpp
clang/test/CXX/over/over.load/p2-0x.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index a20d7dda79300..1eb68090a8fdb 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1316,6 +1316,17 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
(!SameTemplateParameterList || !SameReturnType))
return true;
}
+
+ if (ConsiderRequiresClauses) {
+ Expr *NewRC = New->getTrailingRequiresClause(),
+ *OldRC = Old->getTrailingRequiresClause();
+ if ((NewRC != nullptr) != (OldRC != nullptr))
+ return true;
+
+ if (NewRC && !AreConstraintExpressionsEqual(Old, OldRC, New, NewRC))
+ return true;
+ }
+
// If the function is a class member, its signature includes the
// cv-qualifiers (if any) and ref-qualifier (if any) on the function itself.
//
@@ -1332,14 +1343,15 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
if (!UseMemberUsingDeclRules &&
(OldMethod->getRefQualifier() == RQ_None ||
NewMethod->getRefQualifier() == RQ_None)) {
- // C++0x [over.load]p2:
- // - Member function declarations with the same name and the same
- // parameter-type-list as well as member function template
- // declarations with the same name, the same parameter-type-list, and
- // the same template parameter lists cannot be overloaded if any of
- // them, but not all, have a ref-qualifier (8.3.5).
+ // C++20 [over.load]p2:
+ // - Member function declarations with the same name, the same
+ // parameter-type-list, and the same trailing requires-clause (if
+ // any), as well as member function template declarations with the
+ // same name, the same parameter-type-list, the same trailing
+ // requires-clause (if any), and the same template-head, cannot be
+ // overloaded if any of them, but not all, have a ref-qualifier.
Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload)
- << NewMethod->getRefQualifier() << OldMethod->getRefQualifier();
+ << NewMethod->getRefQualifier() << OldMethod->getRefQualifier();
Diag(OldMethod->getLocation(), diag::note_previous_declaration);
}
return true;
@@ -1403,23 +1415,6 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
}
}
- if (ConsiderRequiresClauses) {
- Expr *NewRC = New->getTrailingRequiresClause(),
- *OldRC = Old->getTrailingRequiresClause();
- if ((NewRC != nullptr) != (OldRC != nullptr))
- // RC are most certainly
diff erent - these are overloads.
- return true;
-
- if (NewRC) {
- llvm::FoldingSetNodeID NewID, OldID;
- NewRC->Profile(NewID, Context, /*Canonical=*/true);
- OldRC->Profile(OldID, Context, /*Canonical=*/true);
- if (NewID != OldID)
- // RCs are not equivalent - these are overloads.
- return true;
- }
- }
-
// The signatures match; this is not an overload.
return false;
}
diff --git a/clang/test/CXX/over/over.load/p2-0x.cpp b/clang/test/CXX/over/over.load/p2-0x.cpp
index cf38741056aba..183f3cb322af7 100644
--- a/clang/test/CXX/over/over.load/p2-0x.cpp
+++ b/clang/test/CXX/over/over.load/p2-0x.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
// Member function declarations with the same name and the same
// parameter-type-list as well as mem- ber function template
@@ -22,3 +23,31 @@ class Y {
void k(); // expected-note{{previous declaration}}
void k() &&; // expected-error{{cannot overload a member function with ref-qualifier '&&' with a member function without a ref-qualifier}}
};
+
+
+#if __cplusplus >= 202002L
+namespace GH58962 {
+
+template<typename T>
+__add_rvalue_reference(T) declval();
+
+template<unsigned R>
+struct type
+{
+ void func() requires (R == 0);
+ void func() & requires (R == 1);
+ void func() && requires (R == 2);
+};
+
+template<typename T>
+concept test = requires { declval<T>().func(); };
+
+static_assert(test<type<0>&>);
+static_assert(test<type<0>&&>);
+static_assert(test<type<1>&>);
+static_assert(not test<type<1>&&>);
+static_assert(not test<type<2>&>);
+static_assert(test<type<2>&&>);
+
+}
+#endif
More information about the cfe-commits
mailing list