[PATCH] D45476: [C++2a] Implement operator<=> CodeGen and ExprConstant

Richard Smith - zygoloid via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 17 03:17:26 PDT 2018


rsmith added inline comments.


================
Comment at: lib/Sema/SemaExpr.cpp:9816
+    RHS = S.ImpCastExprToType(RHS.get(), Type, CK_BitCast);
+  } else {
+    // C++2a [expr.spaceship]p4
----------------
EricWF wrote:
> rsmith wrote:
> > We still need to apply the usual arithmetic conversions after converting enumerations to their underlying types (eg, `<=>` on `enum E : char` converts the operands first to `char` then to `int`). You could remove the `else` here and make this stuff unconditional, but it's probably better to sidestep the extra work and convert directly to the promoted type of the enum's underlying type.
> Do we still do usual arithmetic conversions if we have two enumerations of the same type?
Formally, yes: "If both operands have the same enumeration type E, the operator yields the result of converting the operands to the underlying type of E and applying <=> to the converted operands."

The recursive application of `<=>` to the converted operands will perform the usual arithmetic conversions.


================
Comment at: lib/Sema/SemaExpr.cpp:9794
+  // other is not, the program is ill-formed.
+  if (int Count = LHSType->isBooleanType() + RHSType->isBooleanType()) {
+    // TODO: What about bool non-narrowing cases? Like '0' or '1.
----------------
You could simplify this to `if (LHSType->isBooleanType() != RHSType->isBooleanType()) InvalidOperands`.


================
Comment at: lib/Sema/SemaExpr.cpp:9795
+  if (int Count = LHSType->isBooleanType() + RHSType->isBooleanType()) {
+    // TODO: What about bool non-narrowing cases? Like '0' or '1.
+    if (Count != 2) {
----------------
Missing `'`. Seems like a question to take to Herb and CWG (and maybe EWG), but I suspect the answer will be "this does what we wanted".

Looks like P0946R0 missed this case of a difference between `<=>` and other operators... oops.


================
Comment at: lib/Sema/SemaExpr.cpp:9829-9832
+    if (EDecl->isScoped()) {
+      S.InvalidOperands(Loc, LHS, RHS);
+      return QualType();
+    }
----------------
I don't think you need this check: the usual arithmetic conversions will fail to find a common type if the enum is scoped.


================
Comment at: lib/Sema/SemaExpr.cpp:9881-9890
   enum { StrongEquality, PartialOrdering, StrongOrdering } Ordering;
   if (Type->isAnyComplexType())
     Ordering = StrongEquality;
   else if (Type->isFloatingType())
     Ordering = PartialOrdering;
   else
     Ordering = StrongOrdering;
----------------
This is now over-complicated, since this is unreachable for `BO_Cmp`.


================
Comment at: lib/Sema/SemaExpr.cpp:9906
+  bool IsThreeWay = Opc == BO_Cmp;
+  auto IsPointerType = [](ExprResult E) {
+    QualType Ty = E.get()->getType().getNonReferenceType();
----------------
I'd prefer a name that captures that this also recognizes member pointer types.


================
Comment at: lib/Sema/SemaExpr.cpp:9907
+  auto IsPointerType = [](ExprResult E) {
+    QualType Ty = E.get()->getType().getNonReferenceType();
+    return Ty->isPointerType() || Ty->isMemberPointerType();
----------------
You don't need a `.getNonReferenceType()` here; expressions can't have reference type.


https://reviews.llvm.org/D45476





More information about the cfe-commits mailing list