Commit 5253d913 authored by Richard Smith's avatar Richard Smith
Browse files

[c++20] Determine whether a defaulted comparison should be deleted or

constexpr.
parent c77b4411
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -221,7 +221,6 @@ public:
    return const_cast<ComparisonCategoryInfo *>(This.lookupInfo(Kind));
  }

private:
  const ComparisonCategoryInfo *lookupInfoForType(QualType Ty) const;

private:
+1 −1
Original line number Diff line number Diff line
@@ -113,7 +113,7 @@ def UndefinedVarTemplate : DiagGroup<"undefined-var-template">;
def UndefinedFuncTemplate : DiagGroup<"undefined-func-template">;
def MissingNoEscape : DiagGroup<"missing-noescape">;

def DefaultedComparison : DiagGroup<"defaulted-comparison">;
def DefaultedFunctionDeleted : DiagGroup<"defaulted-function-deleted">;
def DeleteIncomplete : DiagGroup<"delete-incomplete">;
def DeleteNonAbstractNonVirtualDtor : DiagGroup<"delete-non-abstract-non-virtual-dtor">;
def DeleteAbstractNonVirtualDtor : DiagGroup<"delete-abstract-non-virtual-dtor">;
+41 −17
Original line number Diff line number Diff line
@@ -4067,7 +4067,10 @@ def err_ovl_deleted_oper : Error<
  "overload resolution selected deleted operator '%0'">;
def err_ovl_deleted_special_oper : Error<
  "object of type %0 cannot be %select{constructed|copied|moved|assigned|"
  "assigned|destroyed}1 because its %sub{select_special_member_kind}1 is implicitly deleted">;
  "assigned|destroyed}1 because its %sub{select_special_member_kind}1 is "
  "implicitly deleted">;
def err_ovl_deleted_comparison : Error<
  "object of type %0 cannot be compared because its %1 is implicitly deleted">;
def err_ovl_rewrite_equalequal_not_bool : Error<
  "return type %0 of selected 'operator==' function for rewritten "
  "'%1' comparison is not 'bool'">;
@@ -8152,7 +8155,7 @@ def err_incorrect_defaulted_consteval : Error<
  "cannot be consteval because implicit definition is not constexpr">;
def warn_defaulted_method_deleted : Warning<
  "explicitly defaulted %sub{select_special_member_kind}0 is implicitly "
  "deleted">, InGroup<DiagGroup<"defaulted-function-deleted">>;
  "deleted">, InGroup<DefaultedFunctionDeleted>;
def err_out_of_line_default_deletes : Error<
  "defaulting this %sub{select_special_member_kind}0 "
  "would delete it after its first declaration">;
@@ -8194,21 +8197,42 @@ def err_defaulted_comparison_non_const : Error<
def err_defaulted_comparison_return_type_not_bool : Error<
  "return type for defaulted %sub{select_defaulted_comparison_kind}0 "
  "must be 'bool', not %1">;
def err_defaulted_comparison_reference_member : Error<
  "cannot default %0 in class %1 with reference member">;
def ext_defaulted_comparison_reference_member : ExtWarn<
  "ISO C++2a does not allow defaulting %0 in class %1 with reference member">,
  InGroup<DefaultedComparison>;
def note_reference_member : Note<"reference member %0 declared here">;
def err_defaulted_comparison_union : Error<
  "cannot default %0 in %select{union-like class|union}1 %2">;
def ext_defaulted_comparison_union : ExtWarn<
  "ISO C++2a does not allow defaulting %0 in "
  "%select{union-like class|union}1 %2">, InGroup<DefaultedComparison>;
def ext_defaulted_comparison_empty_union : ExtWarn<
  "ISO C++2a does not allow defaulting %0 in "
  "%select{union-like class|union}1 %2 despite it having no variant members">,
  InGroup<DefaultedComparison>;
def warn_defaulted_comparison_deleted : Warning<
  "explicitly defaulted %sub{select_defaulted_comparison_kind}0 is implicitly "
  "deleted">, InGroup<DefaultedFunctionDeleted>;
def err_non_first_default_compare_deletes : Error<
  "defaulting this %sub{select_defaulted_comparison_kind}0 "
  "would delete it after its first declaration">;
def note_defaulted_comparison_union : Note<
  "defaulted %0 is implicitly deleted because "
  "%2 is a %select{union-like class|union}1 with variant members">;
def note_defaulted_comparison_reference_member : Note<
  "defaulted %0 is implicitly deleted because "
  "class %1 has a reference member">;
def note_defaulted_comparison_ambiguous : Note<
  "defaulted %0 is implicitly deleted because implied %select{|'==' |'<' }1"
  "comparison %select{|for member %3 |for base class %3 }2is ambiguous">;
def note_defaulted_comparison_calls_deleted : Note<
  "defaulted %0 is implicitly deleted because it would invoke a deleted "
  "comparison function%select{| for member %2| for base class %2}1">;
def note_defaulted_comparison_no_viable_function : Note<
  "defaulted %0 is implicitly deleted because there is no viable comparison "
  "function%select{| for member %2| for base class %2}1">;
def note_defaulted_comparison_no_viable_function_synthesized : Note<
  "three-way comparison cannot be synthesized because there is no viable "
  "function for %select{'=='|'<'}0 comparison">;
def note_defaulted_comparison_not_rewritten_callee : Note<
  "defaulted %0 is implicitly deleted because this non-rewritten comparison "
  "function would be the best match for the comparison">;
def err_incorrect_defaulted_comparison_constexpr : Error<
  "defaulted definition of %sub{select_defaulted_comparison_kind}0 "
  "cannot be declared %select{constexpr|consteval}1 because it invokes "
  "a non-constexpr comparison function">;
def note_defaulted_comparison_not_constexpr : Note<
  "non-constexpr comparison function would be used to compare "
  "%select{|member %1|base class %1}0">;
def note_defaulted_comparison_not_constexpr_here : Note<
  "non-constexpr comparison function declared here">;

def ext_implicit_exception_spec_mismatch : ExtWarn<
  "function previously declared with an %select{explicit|implicit}0 exception "
+17 −1
Original line number Diff line number Diff line
@@ -935,7 +935,17 @@ class Sema;
      }

      bool isAcceptableCandidate(const FunctionDecl *FD) {
        return AllowRewrittenCandidates || !isRewrittenOperator(FD);
        if (!OriginalOperator)
          return true;

        // For an overloaded operator, we can have candidates with a different
        // name in our unqualified lookup set. Make sure we only consider the
        // ones we're supposed to.
        OverloadedOperatorKind OO =
            FD->getDeclName().getCXXOverloadedOperator();
        return OO && (OO == OriginalOperator ||
                      (AllowRewrittenCandidates &&
                       OO == getRewrittenOverloadedOperator(OriginalOperator)));
      }

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

    /// Exclude a function from being considered by overload resolution.
    void exclude(Decl *F) {
      isNewCandidate(F, OverloadCandidateParamOrder::Normal);
      isNewCandidate(F, OverloadCandidateParamOrder::Reversed);
    }

    /// Clear out all of the candidates.
    void clear(CandidateSetKind CSK);

+7 −0
Original line number Diff line number Diff line
@@ -3310,6 +3310,10 @@ public:
                                     const UnresolvedSetImpl &Fns,
                                     Expr *input, bool RequiresADL = true);
  void LookupOverloadedBinOp(OverloadCandidateSet &CandidateSet,
                             OverloadedOperatorKind Op,
                             const UnresolvedSetImpl &Fns,
                             ArrayRef<Expr *> Args, bool RequiresADL = true);
  ExprResult CreateOverloadedBinOp(SourceLocation OpLoc,
                                   BinaryOperatorKind Opc,
                                   const UnresolvedSetImpl &Fns,
@@ -5310,6 +5314,9 @@ public:
                                 InheritedConstructorInfo *ICI = nullptr,
                                 bool Diagnose = false);
  /// Produce notes explaining why a defaulted function was defined as deleted.
  void DiagnoseDeletedDefaultedFunction(FunctionDecl *FD);
  /// Declare the implicit default constructor for the given class.
  ///
  /// \param ClassDecl The class declaration into which the implicit
Loading