forked from OSchip/llvm-project
[c++20] Improve phrasing of diagnostic for missing #include <compare>.
This commit is contained in:
parent
5688f16852
commit
38c3b5d562
|
@ -10145,8 +10145,8 @@ def warn_dispatch_body_ignored : Warning<
|
||||||
|
|
||||||
// three-way comparison operator diagnostics
|
// three-way comparison operator diagnostics
|
||||||
def err_implied_comparison_category_type_not_found : Error<
|
def err_implied_comparison_category_type_not_found : Error<
|
||||||
"cannot deduce return type of 'operator<=>' because type '%0' was not found; "
|
"cannot %select{use builtin operator '<=>'|default 'operator<=>'}1 "
|
||||||
"include <compare>">;
|
"because type '%0' was not found; include <compare>">;
|
||||||
def err_spaceship_argument_narrowing : Error<
|
def err_spaceship_argument_narrowing : Error<
|
||||||
"argument to 'operator<=>' "
|
"argument to 'operator<=>' "
|
||||||
"%select{cannot be narrowed from type %1 to %2|"
|
"%select{cannot be narrowed from type %1 to %2|"
|
||||||
|
|
|
@ -5038,6 +5038,16 @@ private:
|
||||||
IdentifierInfo *MemberOrBase);
|
IdentifierInfo *MemberOrBase);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum class ComparisonCategoryUsage {
|
||||||
|
/// The '<=>' operator was used in an expression and a builtin operator
|
||||||
|
/// was selected.
|
||||||
|
OperatorInExpression,
|
||||||
|
/// A defaulted 'operator<=>' needed the comparison category. This
|
||||||
|
/// typically only applies to 'std::strong_ordering', due to the implicit
|
||||||
|
/// fallback return value.
|
||||||
|
DefaultedOperator,
|
||||||
|
};
|
||||||
|
|
||||||
/// Lookup the specified comparison category types in the standard
|
/// Lookup the specified comparison category types in the standard
|
||||||
/// library, an check the VarDecls possibly returned by the operator<=>
|
/// library, an check the VarDecls possibly returned by the operator<=>
|
||||||
/// builtins for that type.
|
/// builtins for that type.
|
||||||
|
@ -5045,7 +5055,8 @@ public:
|
||||||
/// \return The type of the comparison category type corresponding to the
|
/// \return The type of the comparison category type corresponding to the
|
||||||
/// specified Kind, or a null type if an error occurs
|
/// specified Kind, or a null type if an error occurs
|
||||||
QualType CheckComparisonCategoryType(ComparisonCategoryType Kind,
|
QualType CheckComparisonCategoryType(ComparisonCategoryType Kind,
|
||||||
SourceLocation Loc);
|
SourceLocation Loc,
|
||||||
|
ComparisonCategoryUsage Usage);
|
||||||
|
|
||||||
/// Tests whether Ty is an instance of std::initializer_list and, if
|
/// Tests whether Ty is an instance of std::initializer_list and, if
|
||||||
/// it is and Element is not NULL, assigns the element type to Element.
|
/// it is and Element is not NULL, assigns the element type to Element.
|
||||||
|
|
|
@ -7599,7 +7599,8 @@ public:
|
||||||
// Per C++2a [class.spaceship]p3, as a fallback add:
|
// Per C++2a [class.spaceship]p3, as a fallback add:
|
||||||
// return static_cast<R>(std::strong_ordering::equal);
|
// return static_cast<R>(std::strong_ordering::equal);
|
||||||
QualType StrongOrdering = S.CheckComparisonCategoryType(
|
QualType StrongOrdering = S.CheckComparisonCategoryType(
|
||||||
ComparisonCategoryType::StrongOrdering, Loc);
|
ComparisonCategoryType::StrongOrdering, Loc,
|
||||||
|
Sema::ComparisonCategoryUsage::DefaultedOperator);
|
||||||
if (StrongOrdering.isNull())
|
if (StrongOrdering.isNull())
|
||||||
return StmtError();
|
return StmtError();
|
||||||
VarDecl *EqualVD = S.Context.CompCategories.getInfoForType(StrongOrdering)
|
VarDecl *EqualVD = S.Context.CompCategories.getInfoForType(StrongOrdering)
|
||||||
|
@ -8057,7 +8058,8 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
|
||||||
RetLoc = FD->getBeginLoc();
|
RetLoc = FD->getBeginLoc();
|
||||||
// FIXME: Should we really care whether we have the complete type and the
|
// FIXME: Should we really care whether we have the complete type and the
|
||||||
// 'enumerator' constants here? A forward declaration seems sufficient.
|
// 'enumerator' constants here? A forward declaration seems sufficient.
|
||||||
QualType Cat = CheckComparisonCategoryType(Info.Category, RetLoc);
|
QualType Cat = CheckComparisonCategoryType(
|
||||||
|
Info.Category, RetLoc, ComparisonCategoryUsage::DefaultedOperator);
|
||||||
if (Cat.isNull())
|
if (Cat.isNull())
|
||||||
return true;
|
return true;
|
||||||
Context.adjustDeducedFunctionResultType(
|
Context.adjustDeducedFunctionResultType(
|
||||||
|
@ -10591,7 +10593,8 @@ struct InvalidSTLDiagnoser {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
QualType Sema::CheckComparisonCategoryType(ComparisonCategoryType Kind,
|
QualType Sema::CheckComparisonCategoryType(ComparisonCategoryType Kind,
|
||||||
SourceLocation Loc) {
|
SourceLocation Loc,
|
||||||
|
ComparisonCategoryUsage Usage) {
|
||||||
assert(getLangOpts().CPlusPlus &&
|
assert(getLangOpts().CPlusPlus &&
|
||||||
"Looking for comparison category type outside of C++.");
|
"Looking for comparison category type outside of C++.");
|
||||||
|
|
||||||
|
@ -10620,7 +10623,7 @@ QualType Sema::CheckComparisonCategoryType(ComparisonCategoryType Kind,
|
||||||
std::string NameForDiags = "std::";
|
std::string NameForDiags = "std::";
|
||||||
NameForDiags += ComparisonCategories::getCategoryString(Kind);
|
NameForDiags += ComparisonCategories::getCategoryString(Kind);
|
||||||
Diag(Loc, diag::err_implied_comparison_category_type_not_found)
|
Diag(Loc, diag::err_implied_comparison_category_type_not_found)
|
||||||
<< NameForDiags;
|
<< NameForDiags << (int)Usage;
|
||||||
return QualType();
|
return QualType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10601,7 +10601,8 @@ static QualType checkArithmeticOrEnumeralThreeWayCompare(Sema &S,
|
||||||
assert(!Type.isNull() && "composite type for <=> has not been set");
|
assert(!Type.isNull() && "composite type for <=> has not been set");
|
||||||
|
|
||||||
return S.CheckComparisonCategoryType(
|
return S.CheckComparisonCategoryType(
|
||||||
*getComparisonCategoryForBuiltinCmp(Type), Loc);
|
*getComparisonCategoryForBuiltinCmp(Type), Loc,
|
||||||
|
Sema::ComparisonCategoryUsage::OperatorInExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QualType checkArithmeticOrEnumeralCompare(Sema &S, ExprResult &LHS,
|
static QualType checkArithmeticOrEnumeralCompare(Sema &S, ExprResult &LHS,
|
||||||
|
@ -10738,7 +10739,8 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
|
||||||
CCT = ComparisonCategoryType::StrongEquality;
|
CCT = ComparisonCategoryType::StrongEquality;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CheckComparisonCategoryType(*CCT, Loc);
|
return CheckComparisonCategoryType(
|
||||||
|
*CCT, Loc, ComparisonCategoryUsage::OperatorInExpression);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!IsRelational && LHSIsNull != RHSIsNull) {
|
if (!IsRelational && LHSIsNull != RHSIsNull) {
|
||||||
|
|
|
@ -3,10 +3,24 @@
|
||||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin -fcxx-exceptions -fsyntax-only -pedantic -verify -Wsign-compare -std=c++2a %s
|
// RUN: %clang_cc1 -triple x86_64-apple-darwin -fcxx-exceptions -fsyntax-only -pedantic -verify -Wsign-compare -std=c++2a %s
|
||||||
|
|
||||||
void compare_not_found_test() {
|
void compare_not_found_test() {
|
||||||
// expected-error@+1 {{cannot deduce return type of 'operator<=>' because type 'std::partial_ordering' was not found; include <compare>}}
|
// expected-error@+1 {{cannot use builtin operator '<=>' because type 'std::partial_ordering' was not found; include <compare>}}
|
||||||
(void)(0.0 <=> 42.123);
|
(void)(0.0 <=> 42.123);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct deduction_compare_not_found {
|
||||||
|
// expected-error@+1 {{cannot default 'operator<=>' because type 'std::strong_ordering' was not found; include <compare>}}
|
||||||
|
friend auto operator<=>(const deduction_compare_not_found&, const deduction_compare_not_found&) = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct comparable {
|
||||||
|
int operator<=>(comparable);
|
||||||
|
};
|
||||||
|
struct default_compare_not_found {
|
||||||
|
// expected-error@+1 {{cannot default 'operator<=>' because type 'std::strong_ordering' was not found; include <compare>}}
|
||||||
|
friend int operator<=>(const default_compare_not_found&, const default_compare_not_found&) = default;
|
||||||
|
};
|
||||||
|
bool b = default_compare_not_found() < default_compare_not_found(); // expected-note {{first required here}}
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
inline namespace __1 {
|
inline namespace __1 {
|
||||||
struct partial_ordering; // expected-note {{forward declaration}}
|
struct partial_ordering; // expected-note {{forward declaration}}
|
||||||
|
|
Loading…
Reference in New Issue