[clang] 38c3b5d - [c++20] Improve phrasing of diagnostic for missing #include <compare>.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 13 18:42:03 PST 2019
Author: Richard Smith
Date: 2019-12-13T18:41:54-08:00
New Revision: 38c3b5d562ac6a5ab0ef5503838aad362af866e0
URL: https://github.com/llvm/llvm-project/commit/38c3b5d562ac6a5ab0ef5503838aad362af866e0
DIFF: https://github.com/llvm/llvm-project/commit/38c3b5d562ac6a5ab0ef5503838aad362af866e0.diff
LOG: [c++20] Improve phrasing of diagnostic for missing #include <compare>.
Added:
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaExpr.cpp
clang/test/SemaCXX/std-compare-cxx2a.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b91fd262c9d3..d657c29adafd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10145,8 +10145,8 @@ def warn_dispatch_body_ignored : Warning<
// three-way comparison operator diagnostics
def err_implied_comparison_category_type_not_found : Error<
- "cannot deduce return type of 'operator<=>' because type '%0' was not found; "
- "include <compare>">;
+ "cannot %select{use builtin operator '<=>'|default 'operator<=>'}1 "
+ "because type '%0' was not found; include <compare>">;
def err_spaceship_argument_narrowing : Error<
"argument to 'operator<=>' "
"%select{cannot be narrowed from type %1 to %2|"
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 53db210a0177..6d0f79a2d2ce 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5038,6 +5038,16 @@ class Sema final {
IdentifierInfo *MemberOrBase);
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
/// library, an check the VarDecls possibly returned by the operator<=>
/// builtins for that type.
@@ -5045,7 +5055,8 @@ class Sema final {
/// \return The type of the comparison category type corresponding to the
/// specified Kind, or a null type if an error occurs
QualType CheckComparisonCategoryType(ComparisonCategoryType Kind,
- SourceLocation Loc);
+ SourceLocation Loc,
+ ComparisonCategoryUsage Usage);
/// 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.
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index ba4d450984a3..239aaf65c86b 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -7599,7 +7599,8 @@ class DefaultedComparisonSynthesizer
// Per C++2a [class.spaceship]p3, as a fallback add:
// return static_cast<R>(std::strong_ordering::equal);
QualType StrongOrdering = S.CheckComparisonCategoryType(
- ComparisonCategoryType::StrongOrdering, Loc);
+ ComparisonCategoryType::StrongOrdering, Loc,
+ Sema::ComparisonCategoryUsage::DefaultedOperator);
if (StrongOrdering.isNull())
return StmtError();
VarDecl *EqualVD = S.Context.CompCategories.getInfoForType(StrongOrdering)
@@ -8057,7 +8058,8 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
RetLoc = FD->getBeginLoc();
// FIXME: Should we really care whether we have the complete type and the
// '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())
return true;
Context.adjustDeducedFunctionResultType(
@@ -10591,7 +10593,8 @@ struct InvalidSTLDiagnoser {
} // namespace
QualType Sema::CheckComparisonCategoryType(ComparisonCategoryType Kind,
- SourceLocation Loc) {
+ SourceLocation Loc,
+ ComparisonCategoryUsage Usage) {
assert(getLangOpts().CPlusPlus &&
"Looking for comparison category type outside of C++.");
@@ -10620,7 +10623,7 @@ QualType Sema::CheckComparisonCategoryType(ComparisonCategoryType Kind,
std::string NameForDiags = "std::";
NameForDiags += ComparisonCategories::getCategoryString(Kind);
Diag(Loc, diag::err_implied_comparison_category_type_not_found)
- << NameForDiags;
+ << NameForDiags << (int)Usage;
return QualType();
}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 36eef4f425e5..a57ee7b0ff21 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -10601,7 +10601,8 @@ static QualType checkArithmeticOrEnumeralThreeWayCompare(Sema &S,
assert(!Type.isNull() && "composite type for <=> has not been set");
return S.CheckComparisonCategoryType(
- *getComparisonCategoryForBuiltinCmp(Type), Loc);
+ *getComparisonCategoryForBuiltinCmp(Type), Loc,
+ Sema::ComparisonCategoryUsage::OperatorInExpression);
}
static QualType checkArithmeticOrEnumeralCompare(Sema &S, ExprResult &LHS,
@@ -10738,7 +10739,8 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
CCT = ComparisonCategoryType::StrongEquality;
}
- return CheckComparisonCategoryType(*CCT, Loc);
+ return CheckComparisonCategoryType(
+ *CCT, Loc, ComparisonCategoryUsage::OperatorInExpression);
};
if (!IsRelational && LHSIsNull != RHSIsNull) {
diff --git a/clang/test/SemaCXX/std-compare-cxx2a.cpp b/clang/test/SemaCXX/std-compare-cxx2a.cpp
index 941c4faeb7ff..3febb8ff4399 100644
--- a/clang/test/SemaCXX/std-compare-cxx2a.cpp
+++ b/clang/test/SemaCXX/std-compare-cxx2a.cpp
@@ -3,10 +3,24 @@
// 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() {
- // expected-error at +1 {{cannot deduce return type of 'operator<=>' because type 'std::partial_ordering' was not found; include <compare>}}
+ // expected-error at +1 {{cannot use builtin operator '<=>' because type 'std::partial_ordering' was not found; include <compare>}}
(void)(0.0 <=> 42.123);
}
+struct deduction_compare_not_found {
+ // expected-error at +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 at +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 {
inline namespace __1 {
struct partial_ordering; // expected-note {{forward declaration}}
More information about the cfe-commits
mailing list