Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2065,9 +2065,9 @@ The following type trait primitives are supported by Clang. Those traits marked
Returns true if a reference ``T`` can be copy-initialized from a temporary of type
a non-cv-qualified ``U``.
* ``__underlying_type`` (C++, GNU, Microsoft)
* ``__builtin_lt_synthesises_from_spaceship``, ``__builtin_gt_synthesises_from_spaceship``,
``__builtin_le_synthesises_from_spaceship``, ``__builtin_ge_synthesises_from_spaceship`` (Clang):
These builtins can be used to determine whether the corresponding operator is synthesised from a spaceship operator.
* ``__builtin_lt_synthesizes_from_spaceship``, ``__builtin_gt_synthesizes_from_spaceship``,
``__builtin_le_synthesizes_from_spaceship``, ``__builtin_ge_synthesizes_from_spaceship`` (Clang):
These builtins can be used to determine whether the corresponding operator is synthesized from a spaceship operator.

In addition, the following expression traits are supported:

Expand Down
4 changes: 2 additions & 2 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ What's New in Clang |release|?
C++ Language Changes
--------------------

- A new family of builtins ``__builtin_*_synthesises_from_spaceship`` has been added. These can be queried to know
whether the ``<`` (``lt``), ``>`` (``gt``), ``<=`` (``le``), or ``>=`` (``ge``) operators are synthesised from a
- A new family of builtins ``__builtin_*_synthesizes_from_spaceship`` has been added. These can be queried to know
whether the ``<`` (``lt``), ``>`` (``gt``), ``<=`` (``le``), or ``>=`` (``ge``) operators are synthesized from a
``<=>``. This makes it possible to optimize certain facilities by using the ``<=>`` operation directly instead of
doing multiple comparisons.

Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -552,10 +552,10 @@ TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
TYPE_TRAIT_2(__reference_constructs_from_temporary, ReferenceConstructsFromTemporary, KEYCXX)
TYPE_TRAIT_2(__reference_converts_from_temporary, ReferenceConvertsFromTemporary, KEYCXX)
TYPE_TRAIT_2(__builtin_lt_synthesises_from_spaceship, LtSynthesisesFromSpaceship, KEYCXX)
TYPE_TRAIT_2(__builtin_le_synthesises_from_spaceship, LeSynthesisesFromSpaceship, KEYCXX)
TYPE_TRAIT_2(__builtin_gt_synthesises_from_spaceship, GtSynthesisesFromSpaceship, KEYCXX)
TYPE_TRAIT_2(__builtin_ge_synthesises_from_spaceship, GeSynthesisesFromSpaceship, KEYCXX)
TYPE_TRAIT_2(__builtin_lt_synthesizes_from_spaceship, LtSynthesizesFromSpaceship, KEYCXX)
TYPE_TRAIT_2(__builtin_le_synthesizes_from_spaceship, LeSynthesizesFromSpaceship, KEYCXX)
TYPE_TRAIT_2(__builtin_gt_synthesizes_from_spaceship, GtSynthesizesFromSpaceship, KEYCXX)
TYPE_TRAIT_2(__builtin_ge_synthesizes_from_spaceship, GeSynthesizesFromSpaceship, KEYCXX)
// IsDeducible is only used internally by clang for CTAD implementation and
// is not exposed to users.
TYPE_TRAIT_2(/*EmptySpellingName*/, IsDeducible, KEYCXX)
Expand Down
16 changes: 8 additions & 8 deletions clang/lib/Sema/SemaTypeTraits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1827,10 +1827,10 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,

return Self.HLSL().IsScalarizedLayoutCompatible(LhsT, RhsT);
}
case BTT_LtSynthesisesFromSpaceship:
case BTT_LeSynthesisesFromSpaceship:
case BTT_GtSynthesisesFromSpaceship:
case BTT_GeSynthesisesFromSpaceship: {
case BTT_LtSynthesizesFromSpaceship:
case BTT_LeSynthesizesFromSpaceship:
case BTT_GtSynthesizesFromSpaceship:
case BTT_GeSynthesizesFromSpaceship: {
EnterExpressionEvaluationContext UnevaluatedContext(
Self, Sema::ExpressionEvaluationContext::Unevaluated);
Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
Expand All @@ -1849,13 +1849,13 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,

auto OpKind = [&] {
switch (BTT) {
case BTT_LtSynthesisesFromSpaceship:
case BTT_LtSynthesizesFromSpaceship:
return BinaryOperatorKind::BO_LT;
case BTT_LeSynthesisesFromSpaceship:
case BTT_LeSynthesizesFromSpaceship:
return BinaryOperatorKind::BO_LE;
case BTT_GtSynthesisesFromSpaceship:
case BTT_GtSynthesizesFromSpaceship:
return BinaryOperatorKind::BO_GT;
case BTT_GeSynthesisesFromSpaceship:
case BTT_GeSynthesizesFromSpaceship:
return BinaryOperatorKind::BO_GE;
default:
llvm_unreachable("Trying to Synthesize non-comparison operator?");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s

static_assert(!__builtin_lt_synthesises_from_spaceship()); // expected-error {{expected a type}}
static_assert(!__builtin_lt_synthesises_from_spaceship(int)); // expected-error {{type trait requires 2 arguments; have 1 argument}}
static_assert(!__builtin_lt_synthesises_from_spaceship(int, int, int)); // expected-error {{type trait requires 2 arguments; have 3 argument}}
static_assert(!__builtin_lt_synthesises_from_spaceship(int, 0)); // expected-error {{expected a type}}

static_assert(!__builtin_le_synthesises_from_spaceship()); // expected-error {{expected a type}}
static_assert(!__builtin_le_synthesises_from_spaceship(int)); // expected-error {{type trait requires 2 arguments; have 1 argument}}
static_assert(!__builtin_le_synthesises_from_spaceship(int, int, int)); // expected-error {{type trait requires 2 arguments; have 3 argument}}
static_assert(!__builtin_le_synthesises_from_spaceship(int, 0)); // expected-error {{expected a type}}

static_assert(!__builtin_gt_synthesises_from_spaceship()); // expected-error {{expected a type}}
static_assert(!__builtin_gt_synthesises_from_spaceship(int)); // expected-error {{type trait requires 2 arguments; have 1 argument}}
static_assert(!__builtin_gt_synthesises_from_spaceship(int, int, int)); // expected-error {{type trait requires 2 arguments; have 3 argument}}
static_assert(!__builtin_gt_synthesises_from_spaceship(int, 0)); // expected-error {{expected a type}}

static_assert(!__builtin_ge_synthesises_from_spaceship()); // expected-error {{expected a type}}
static_assert(!__builtin_ge_synthesises_from_spaceship(int)); // expected-error {{type trait requires 2 arguments; have 1 argument}}
static_assert(!__builtin_ge_synthesises_from_spaceship(int, int, int)); // expected-error {{type trait requires 2 arguments; have 3 argument}}
static_assert(!__builtin_ge_synthesises_from_spaceship(int, 0)); // expected-error {{expected a type}}
static_assert(!__builtin_lt_synthesizes_from_spaceship()); // expected-error {{expected a type}}
static_assert(!__builtin_lt_synthesizes_from_spaceship(int)); // expected-error {{type trait requires 2 arguments; have 1 argument}}
static_assert(!__builtin_lt_synthesizes_from_spaceship(int, int, int)); // expected-error {{type trait requires 2 arguments; have 3 argument}}
static_assert(!__builtin_lt_synthesizes_from_spaceship(int, 0)); // expected-error {{expected a type}}

static_assert(!__builtin_le_synthesizes_from_spaceship()); // expected-error {{expected a type}}
static_assert(!__builtin_le_synthesizes_from_spaceship(int)); // expected-error {{type trait requires 2 arguments; have 1 argument}}
static_assert(!__builtin_le_synthesizes_from_spaceship(int, int, int)); // expected-error {{type trait requires 2 arguments; have 3 argument}}
static_assert(!__builtin_le_synthesizes_from_spaceship(int, 0)); // expected-error {{expected a type}}

static_assert(!__builtin_gt_synthesizes_from_spaceship()); // expected-error {{expected a type}}
static_assert(!__builtin_gt_synthesizes_from_spaceship(int)); // expected-error {{type trait requires 2 arguments; have 1 argument}}
static_assert(!__builtin_gt_synthesizes_from_spaceship(int, int, int)); // expected-error {{type trait requires 2 arguments; have 3 argument}}
static_assert(!__builtin_gt_synthesizes_from_spaceship(int, 0)); // expected-error {{expected a type}}

static_assert(!__builtin_ge_synthesizes_from_spaceship()); // expected-error {{expected a type}}
static_assert(!__builtin_ge_synthesizes_from_spaceship(int)); // expected-error {{type trait requires 2 arguments; have 1 argument}}
static_assert(!__builtin_ge_synthesizes_from_spaceship(int, int, int)); // expected-error {{type trait requires 2 arguments; have 3 argument}}
static_assert(!__builtin_ge_synthesizes_from_spaceship(int, 0)); // expected-error {{expected a type}}

namespace std {
struct strong_ordering {
Expand All @@ -35,10 +35,10 @@ struct DefaultSpaceship {
friend auto operator<=>(DefaultSpaceship, DefaultSpaceship) = default;
};

static_assert(__builtin_lt_synthesises_from_spaceship(const DefaultSpaceship&, const DefaultSpaceship&));
static_assert(__builtin_le_synthesises_from_spaceship(const DefaultSpaceship&, const DefaultSpaceship&));
static_assert(__builtin_gt_synthesises_from_spaceship(const DefaultSpaceship&, const DefaultSpaceship&));
static_assert(__builtin_ge_synthesises_from_spaceship(const DefaultSpaceship&, const DefaultSpaceship&));
static_assert(__builtin_lt_synthesizes_from_spaceship(const DefaultSpaceship&, const DefaultSpaceship&));
static_assert(__builtin_le_synthesizes_from_spaceship(const DefaultSpaceship&, const DefaultSpaceship&));
static_assert(__builtin_gt_synthesizes_from_spaceship(const DefaultSpaceship&, const DefaultSpaceship&));
static_assert(__builtin_ge_synthesizes_from_spaceship(const DefaultSpaceship&, const DefaultSpaceship&));

struct CustomSpaceship {
int i;
Expand All @@ -48,10 +48,10 @@ struct CustomSpaceship {
}
};

static_assert(__builtin_lt_synthesises_from_spaceship(const CustomSpaceship&, const CustomSpaceship&));
static_assert(__builtin_le_synthesises_from_spaceship(const CustomSpaceship&, const CustomSpaceship&));
static_assert(__builtin_gt_synthesises_from_spaceship(const CustomSpaceship&, const CustomSpaceship&));
static_assert(__builtin_ge_synthesises_from_spaceship(const CustomSpaceship&, const CustomSpaceship&));
static_assert(__builtin_lt_synthesizes_from_spaceship(const CustomSpaceship&, const CustomSpaceship&));
static_assert(__builtin_le_synthesizes_from_spaceship(const CustomSpaceship&, const CustomSpaceship&));
static_assert(__builtin_gt_synthesizes_from_spaceship(const CustomSpaceship&, const CustomSpaceship&));
static_assert(__builtin_ge_synthesizes_from_spaceship(const CustomSpaceship&, const CustomSpaceship&));

struct CustomLT {
int i;
Expand All @@ -61,10 +61,10 @@ struct CustomLT {
}
};

static_assert(!__builtin_lt_synthesises_from_spaceship(const CustomLT&, const CustomLT&));
static_assert(!__builtin_le_synthesises_from_spaceship(const CustomLT&, const CustomLT&));
static_assert(!__builtin_gt_synthesises_from_spaceship(const CustomLT&, const CustomLT&));
static_assert(!__builtin_ge_synthesises_from_spaceship(const CustomLT&, const CustomLT&));
static_assert(!__builtin_lt_synthesizes_from_spaceship(const CustomLT&, const CustomLT&));
static_assert(!__builtin_le_synthesizes_from_spaceship(const CustomLT&, const CustomLT&));
static_assert(!__builtin_gt_synthesizes_from_spaceship(const CustomLT&, const CustomLT&));
static_assert(!__builtin_ge_synthesizes_from_spaceship(const CustomLT&, const CustomLT&));

struct CustomLE {
int i;
Expand All @@ -74,10 +74,10 @@ struct CustomLE {
}
};

static_assert(!__builtin_lt_synthesises_from_spaceship(const CustomLE&, const CustomLE&));
static_assert(!__builtin_le_synthesises_from_spaceship(const CustomLE&, const CustomLE&));
static_assert(!__builtin_gt_synthesises_from_spaceship(const CustomLE&, const CustomLE&));
static_assert(!__builtin_ge_synthesises_from_spaceship(const CustomLE&, const CustomLE&));
static_assert(!__builtin_lt_synthesizes_from_spaceship(const CustomLE&, const CustomLE&));
static_assert(!__builtin_le_synthesizes_from_spaceship(const CustomLE&, const CustomLE&));
static_assert(!__builtin_gt_synthesizes_from_spaceship(const CustomLE&, const CustomLE&));
static_assert(!__builtin_ge_synthesizes_from_spaceship(const CustomLE&, const CustomLE&));

struct CustomGT {
int i;
Expand All @@ -87,10 +87,10 @@ struct CustomGT {
}
};

static_assert(!__builtin_lt_synthesises_from_spaceship(const CustomGT&, const CustomGT&));
static_assert(!__builtin_le_synthesises_from_spaceship(const CustomGT&, const CustomGT&));
static_assert(!__builtin_gt_synthesises_from_spaceship(const CustomGT&, const CustomGT&));
static_assert(!__builtin_ge_synthesises_from_spaceship(const CustomGT&, const CustomGT&));
static_assert(!__builtin_lt_synthesizes_from_spaceship(const CustomGT&, const CustomGT&));
static_assert(!__builtin_le_synthesizes_from_spaceship(const CustomGT&, const CustomGT&));
static_assert(!__builtin_gt_synthesizes_from_spaceship(const CustomGT&, const CustomGT&));
static_assert(!__builtin_ge_synthesizes_from_spaceship(const CustomGT&, const CustomGT&));

struct CustomGE {
int i;
Expand All @@ -100,10 +100,10 @@ struct CustomGE {
}
};

static_assert(!__builtin_lt_synthesises_from_spaceship(const CustomGE&, const CustomGE&));
static_assert(!__builtin_le_synthesises_from_spaceship(const CustomGE&, const CustomGE&));
static_assert(!__builtin_gt_synthesises_from_spaceship(const CustomGE&, const CustomGE&));
static_assert(!__builtin_ge_synthesises_from_spaceship(const CustomGE&, const CustomGE&));
static_assert(!__builtin_lt_synthesizes_from_spaceship(const CustomGE&, const CustomGE&));
static_assert(!__builtin_le_synthesizes_from_spaceship(const CustomGE&, const CustomGE&));
static_assert(!__builtin_gt_synthesizes_from_spaceship(const CustomGE&, const CustomGE&));
static_assert(!__builtin_ge_synthesizes_from_spaceship(const CustomGE&, const CustomGE&));

struct CustomLTAndSpaceship {
int i;
Expand All @@ -117,10 +117,10 @@ struct CustomLTAndSpaceship {
}
};

static_assert(!__builtin_lt_synthesises_from_spaceship(const CustomLTAndSpaceship&, const CustomLTAndSpaceship&));
static_assert(__builtin_le_synthesises_from_spaceship(const CustomLTAndSpaceship&, const CustomLTAndSpaceship&));
static_assert(__builtin_gt_synthesises_from_spaceship(const CustomLTAndSpaceship&, const CustomLTAndSpaceship&));
static_assert(__builtin_ge_synthesises_from_spaceship(const CustomLTAndSpaceship&, const CustomLTAndSpaceship&));
static_assert(!__builtin_lt_synthesizes_from_spaceship(const CustomLTAndSpaceship&, const CustomLTAndSpaceship&));
static_assert(__builtin_le_synthesizes_from_spaceship(const CustomLTAndSpaceship&, const CustomLTAndSpaceship&));
static_assert(__builtin_gt_synthesizes_from_spaceship(const CustomLTAndSpaceship&, const CustomLTAndSpaceship&));
static_assert(__builtin_ge_synthesizes_from_spaceship(const CustomLTAndSpaceship&, const CustomLTAndSpaceship&));

struct CustomLEAndSpaceship {
int i;
Expand All @@ -134,10 +134,10 @@ struct CustomLEAndSpaceship {
}
};

static_assert(__builtin_lt_synthesises_from_spaceship(const CustomLEAndSpaceship&, const CustomLEAndSpaceship&));
static_assert(!__builtin_le_synthesises_from_spaceship(const CustomLEAndSpaceship&, const CustomLEAndSpaceship&));
static_assert(__builtin_gt_synthesises_from_spaceship(const CustomLEAndSpaceship&, const CustomLEAndSpaceship&));
static_assert(__builtin_ge_synthesises_from_spaceship(const CustomLEAndSpaceship&, const CustomLEAndSpaceship&));
static_assert(__builtin_lt_synthesizes_from_spaceship(const CustomLEAndSpaceship&, const CustomLEAndSpaceship&));
static_assert(!__builtin_le_synthesizes_from_spaceship(const CustomLEAndSpaceship&, const CustomLEAndSpaceship&));
static_assert(__builtin_gt_synthesizes_from_spaceship(const CustomLEAndSpaceship&, const CustomLEAndSpaceship&));
static_assert(__builtin_ge_synthesizes_from_spaceship(const CustomLEAndSpaceship&, const CustomLEAndSpaceship&));

struct CustomGTAndSpaceship {
int i;
Expand All @@ -151,10 +151,10 @@ struct CustomGTAndSpaceship {
}
};

static_assert(__builtin_lt_synthesises_from_spaceship(const CustomGTAndSpaceship&, const CustomGTAndSpaceship&));
static_assert(__builtin_le_synthesises_from_spaceship(const CustomGTAndSpaceship&, const CustomGTAndSpaceship&));
static_assert(!__builtin_gt_synthesises_from_spaceship(const CustomGTAndSpaceship&, const CustomGTAndSpaceship&));
static_assert(__builtin_ge_synthesises_from_spaceship(const CustomGTAndSpaceship&, const CustomGTAndSpaceship&));
static_assert(__builtin_lt_synthesizes_from_spaceship(const CustomGTAndSpaceship&, const CustomGTAndSpaceship&));
static_assert(__builtin_le_synthesizes_from_spaceship(const CustomGTAndSpaceship&, const CustomGTAndSpaceship&));
static_assert(!__builtin_gt_synthesizes_from_spaceship(const CustomGTAndSpaceship&, const CustomGTAndSpaceship&));
static_assert(__builtin_ge_synthesizes_from_spaceship(const CustomGTAndSpaceship&, const CustomGTAndSpaceship&));

struct CustomGEAndSpaceship {
int i;
Expand All @@ -168,10 +168,10 @@ struct CustomGEAndSpaceship {
}
};

static_assert(__builtin_lt_synthesises_from_spaceship(const CustomGEAndSpaceship&, const CustomGEAndSpaceship&));
static_assert(__builtin_le_synthesises_from_spaceship(const CustomGEAndSpaceship&, const CustomGEAndSpaceship&));
static_assert(__builtin_gt_synthesises_from_spaceship(const CustomGEAndSpaceship&, const CustomGEAndSpaceship&));
static_assert(!__builtin_ge_synthesises_from_spaceship(const CustomGEAndSpaceship&, const CustomGEAndSpaceship&));
static_assert(__builtin_lt_synthesizes_from_spaceship(const CustomGEAndSpaceship&, const CustomGEAndSpaceship&));
static_assert(__builtin_le_synthesizes_from_spaceship(const CustomGEAndSpaceship&, const CustomGEAndSpaceship&));
static_assert(__builtin_gt_synthesizes_from_spaceship(const CustomGEAndSpaceship&, const CustomGEAndSpaceship&));
static_assert(!__builtin_ge_synthesizes_from_spaceship(const CustomGEAndSpaceship&, const CustomGEAndSpaceship&));

struct DefaultedCmpAndSpaceship {
int i;
Expand All @@ -187,10 +187,10 @@ struct DefaultedCmpAndSpaceship {
};

// TODO: This should probably return true
static_assert(!__builtin_lt_synthesises_from_spaceship(const DefaultedCmpAndSpaceship&, const DefaultedCmpAndSpaceship&));
static_assert(!__builtin_le_synthesises_from_spaceship(const DefaultedCmpAndSpaceship&, const DefaultedCmpAndSpaceship&));
static_assert(!__builtin_gt_synthesises_from_spaceship(const DefaultedCmpAndSpaceship&, const DefaultedCmpAndSpaceship&));
static_assert(!__builtin_ge_synthesises_from_spaceship(const DefaultedCmpAndSpaceship&, const DefaultedCmpAndSpaceship&));
static_assert(!__builtin_lt_synthesizes_from_spaceship(const DefaultedCmpAndSpaceship&, const DefaultedCmpAndSpaceship&));
static_assert(!__builtin_le_synthesizes_from_spaceship(const DefaultedCmpAndSpaceship&, const DefaultedCmpAndSpaceship&));
static_assert(!__builtin_gt_synthesizes_from_spaceship(const DefaultedCmpAndSpaceship&, const DefaultedCmpAndSpaceship&));
static_assert(!__builtin_ge_synthesizes_from_spaceship(const DefaultedCmpAndSpaceship&, const DefaultedCmpAndSpaceship&));

struct DifferentTypes {
int i;
Expand All @@ -200,13 +200,13 @@ struct DifferentTypes {
}
};

static_assert(__builtin_lt_synthesises_from_spaceship(const DifferentTypes&, const int&));
static_assert(__builtin_le_synthesises_from_spaceship(const DifferentTypes&, const int&));
static_assert(__builtin_gt_synthesises_from_spaceship(const DifferentTypes&, const int&));
static_assert(__builtin_ge_synthesises_from_spaceship(const DifferentTypes&, const int&));
static_assert(__builtin_lt_synthesizes_from_spaceship(const DifferentTypes&, const int&));
static_assert(__builtin_le_synthesizes_from_spaceship(const DifferentTypes&, const int&));
static_assert(__builtin_gt_synthesizes_from_spaceship(const DifferentTypes&, const int&));
static_assert(__builtin_ge_synthesizes_from_spaceship(const DifferentTypes&, const int&));

// TODO: Should this return true? It's technically not synthesized from spaceship, but it behaves exactly as-if it was
static_assert(!__builtin_lt_synthesises_from_spaceship(int, int));
static_assert(!__builtin_le_synthesises_from_spaceship(int, int));
static_assert(!__builtin_gt_synthesises_from_spaceship(int, int));
static_assert(!__builtin_ge_synthesises_from_spaceship(int, int));
static_assert(!__builtin_lt_synthesizes_from_spaceship(int, int));
static_assert(!__builtin_le_synthesizes_from_spaceship(int, int));
static_assert(!__builtin_gt_synthesizes_from_spaceship(int, int));
static_assert(!__builtin_ge_synthesizes_from_spaceship(int, int));
Loading
Loading