Skip to content

Commit 5253d91

Browse files
committed
[c++20] Determine whether a defaulted comparison should be deleted or
constexpr.
1 parent c77b441 commit 5253d91

File tree

16 files changed

+1126
-218
lines changed

16 files changed

+1126
-218
lines changed

clang/include/clang/AST/ComparisonCategories.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,6 @@ class ComparisonCategories {
221221
return const_cast<ComparisonCategoryInfo *>(This.lookupInfo(Kind));
222222
}
223223

224-
private:
225224
const ComparisonCategoryInfo *lookupInfoForType(QualType Ty) const;
226225

227226
private:

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def UndefinedVarTemplate : DiagGroup<"undefined-var-template">;
113113
def UndefinedFuncTemplate : DiagGroup<"undefined-func-template">;
114114
def MissingNoEscape : DiagGroup<"missing-noescape">;
115115

116-
def DefaultedComparison : DiagGroup<"defaulted-comparison">;
116+
def DefaultedFunctionDeleted : DiagGroup<"defaulted-function-deleted">;
117117
def DeleteIncomplete : DiagGroup<"delete-incomplete">;
118118
def DeleteNonAbstractNonVirtualDtor : DiagGroup<"delete-non-abstract-non-virtual-dtor">;
119119
def DeleteAbstractNonVirtualDtor : DiagGroup<"delete-abstract-non-virtual-dtor">;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4067,7 +4067,10 @@ def err_ovl_deleted_oper : Error<
40674067
"overload resolution selected deleted operator '%0'">;
40684068
def err_ovl_deleted_special_oper : Error<
40694069
"object of type %0 cannot be %select{constructed|copied|moved|assigned|"
4070-
"assigned|destroyed}1 because its %sub{select_special_member_kind}1 is implicitly deleted">;
4070+
"assigned|destroyed}1 because its %sub{select_special_member_kind}1 is "
4071+
"implicitly deleted">;
4072+
def err_ovl_deleted_comparison : Error<
4073+
"object of type %0 cannot be compared because its %1 is implicitly deleted">;
40714074
def err_ovl_rewrite_equalequal_not_bool : Error<
40724075
"return type %0 of selected 'operator==' function for rewritten "
40734076
"'%1' comparison is not 'bool'">;
@@ -8152,7 +8155,7 @@ def err_incorrect_defaulted_consteval : Error<
81528155
"cannot be consteval because implicit definition is not constexpr">;
81538156
def warn_defaulted_method_deleted : Warning<
81548157
"explicitly defaulted %sub{select_special_member_kind}0 is implicitly "
8155-
"deleted">, InGroup<DiagGroup<"defaulted-function-deleted">>;
8158+
"deleted">, InGroup<DefaultedFunctionDeleted>;
81568159
def err_out_of_line_default_deletes : Error<
81578160
"defaulting this %sub{select_special_member_kind}0 "
81588161
"would delete it after its first declaration">;
@@ -8194,21 +8197,42 @@ def err_defaulted_comparison_non_const : Error<
81948197
def err_defaulted_comparison_return_type_not_bool : Error<
81958198
"return type for defaulted %sub{select_defaulted_comparison_kind}0 "
81968199
"must be 'bool', not %1">;
8197-
def err_defaulted_comparison_reference_member : Error<
8198-
"cannot default %0 in class %1 with reference member">;
8199-
def ext_defaulted_comparison_reference_member : ExtWarn<
8200-
"ISO C++2a does not allow defaulting %0 in class %1 with reference member">,
8201-
InGroup<DefaultedComparison>;
8202-
def note_reference_member : Note<"reference member %0 declared here">;
8203-
def err_defaulted_comparison_union : Error<
8204-
"cannot default %0 in %select{union-like class|union}1 %2">;
8205-
def ext_defaulted_comparison_union : ExtWarn<
8206-
"ISO C++2a does not allow defaulting %0 in "
8207-
"%select{union-like class|union}1 %2">, InGroup<DefaultedComparison>;
8208-
def ext_defaulted_comparison_empty_union : ExtWarn<
8209-
"ISO C++2a does not allow defaulting %0 in "
8210-
"%select{union-like class|union}1 %2 despite it having no variant members">,
8211-
InGroup<DefaultedComparison>;
8200+
def warn_defaulted_comparison_deleted : Warning<
8201+
"explicitly defaulted %sub{select_defaulted_comparison_kind}0 is implicitly "
8202+
"deleted">, InGroup<DefaultedFunctionDeleted>;
8203+
def err_non_first_default_compare_deletes : Error<
8204+
"defaulting this %sub{select_defaulted_comparison_kind}0 "
8205+
"would delete it after its first declaration">;
8206+
def note_defaulted_comparison_union : Note<
8207+
"defaulted %0 is implicitly deleted because "
8208+
"%2 is a %select{union-like class|union}1 with variant members">;
8209+
def note_defaulted_comparison_reference_member : Note<
8210+
"defaulted %0 is implicitly deleted because "
8211+
"class %1 has a reference member">;
8212+
def note_defaulted_comparison_ambiguous : Note<
8213+
"defaulted %0 is implicitly deleted because implied %select{|'==' |'<' }1"
8214+
"comparison %select{|for member %3 |for base class %3 }2is ambiguous">;
8215+
def note_defaulted_comparison_calls_deleted : Note<
8216+
"defaulted %0 is implicitly deleted because it would invoke a deleted "
8217+
"comparison function%select{| for member %2| for base class %2}1">;
8218+
def note_defaulted_comparison_no_viable_function : Note<
8219+
"defaulted %0 is implicitly deleted because there is no viable comparison "
8220+
"function%select{| for member %2| for base class %2}1">;
8221+
def note_defaulted_comparison_no_viable_function_synthesized : Note<
8222+
"three-way comparison cannot be synthesized because there is no viable "
8223+
"function for %select{'=='|'<'}0 comparison">;
8224+
def note_defaulted_comparison_not_rewritten_callee : Note<
8225+
"defaulted %0 is implicitly deleted because this non-rewritten comparison "
8226+
"function would be the best match for the comparison">;
8227+
def err_incorrect_defaulted_comparison_constexpr : Error<
8228+
"defaulted definition of %sub{select_defaulted_comparison_kind}0 "
8229+
"cannot be declared %select{constexpr|consteval}1 because it invokes "
8230+
"a non-constexpr comparison function">;
8231+
def note_defaulted_comparison_not_constexpr : Note<
8232+
"non-constexpr comparison function would be used to compare "
8233+
"%select{|member %1|base class %1}0">;
8234+
def note_defaulted_comparison_not_constexpr_here : Note<
8235+
"non-constexpr comparison function declared here">;
82128236

82138237
def ext_implicit_exception_spec_mismatch : ExtWarn<
82148238
"function previously declared with an %select{explicit|implicit}0 exception "

clang/include/clang/Sema/Overload.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,17 @@ class Sema;
935935
}
936936

937937
bool isAcceptableCandidate(const FunctionDecl *FD) {
938-
return AllowRewrittenCandidates || !isRewrittenOperator(FD);
938+
if (!OriginalOperator)
939+
return true;
940+
941+
// For an overloaded operator, we can have candidates with a different
942+
// name in our unqualified lookup set. Make sure we only consider the
943+
// ones we're supposed to.
944+
OverloadedOperatorKind OO =
945+
FD->getDeclName().getCXXOverloadedOperator();
946+
return OO && (OO == OriginalOperator ||
947+
(AllowRewrittenCandidates &&
948+
OO == getRewrittenOverloadedOperator(OriginalOperator)));
939949
}
940950

941951
/// Determine the kind of rewrite that should be performed for this
@@ -1028,6 +1038,12 @@ class Sema;
10281038
return Functions.insert(Key).second;
10291039
}
10301040

1041+
/// Exclude a function from being considered by overload resolution.
1042+
void exclude(Decl *F) {
1043+
isNewCandidate(F, OverloadCandidateParamOrder::Normal);
1044+
isNewCandidate(F, OverloadCandidateParamOrder::Reversed);
1045+
}
1046+
10311047
/// Clear out all of the candidates.
10321048
void clear(CandidateSetKind CSK);
10331049

clang/include/clang/Sema/Sema.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3310,6 +3310,10 @@ class Sema final {
33103310
const UnresolvedSetImpl &Fns,
33113311
Expr *input, bool RequiresADL = true);
33123312

3313+
void LookupOverloadedBinOp(OverloadCandidateSet &CandidateSet,
3314+
OverloadedOperatorKind Op,
3315+
const UnresolvedSetImpl &Fns,
3316+
ArrayRef<Expr *> Args, bool RequiresADL = true);
33133317
ExprResult CreateOverloadedBinOp(SourceLocation OpLoc,
33143318
BinaryOperatorKind Opc,
33153319
const UnresolvedSetImpl &Fns,
@@ -5310,6 +5314,9 @@ class Sema final {
53105314
InheritedConstructorInfo *ICI = nullptr,
53115315
bool Diagnose = false);
53125316

5317+
/// Produce notes explaining why a defaulted function was defined as deleted.
5318+
void DiagnoseDeletedDefaultedFunction(FunctionDecl *FD);
5319+
53135320
/// Declare the implicit default constructor for the given class.
53145321
///
53155322
/// \param ClassDecl The class declaration into which the implicit

0 commit comments

Comments
 (0)