Next version, addresses the review comments. Tested at https://github.com/D-Programming-GDC/GDC/pull/768 --- gcc/d/ChangeLog:
2018-11-28 Johannes Pfau <johannesp...@gmail.com> * expr.cc (ExprVisitor::visit(IdentityExp)): Add support for complex types. (build_float_identity): New function. gcc/testsuite/ChangeLog: 2018-11-28 Johannes Pfau <johannesp...@gmail.com> * gdc.dg/runnable.d: Test IdentityExp for complex types. gcc/d/expr.cc | 40 ++++++++++++++++++++++++--------- gcc/testsuite/gdc.dg/runnable.d | 22 ++++++++++++++++++ 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 9a1aad42ddc..91cb02f1e9a 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -42,6 +42,20 @@ along with GCC; see the file COPYING3. If not see #include "d-tree.h" +/* Helper function for floating point identity comparison. Compare + only well-defined bits, ignore padding (e.g. for X86 80bit real). */ + +static tree build_float_identity (tree_code code, tree t1, tree t2) +{ + /* For floating-point values, identity is defined as the bits in the + operands being identical. */ + tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP); + tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT); + + tree result = build_call_expr (tmemcmp, 3, build_address (t1), + build_address (t2), size); + return build_boolop (code, result, integer_zero_node); +} /* Implements the visitor interface to build the GCC trees of all Expression AST classes emitted from the D Front-end. @@ -275,19 +289,23 @@ public: this->result_ = d_convert (build_ctype (e->type), build_boolop (code, t1, t2)); } - else if (tb1->isfloating () && tb1->ty != Tvector) + else if (tb1->iscomplex () && tb1->ty != Tvector) { - /* For floating-point values, identity is defined as the bits in the - operands being identical. */ - tree t1 = d_save_expr (build_expr (e->e1)); - tree t2 = d_save_expr (build_expr (e->e2)); - - tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP); - tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT); + tree e1 = d_save_expr (build_expr (e->e1)); + tree e2 = d_save_expr (build_expr (e->e2)); + tree req = build_float_identity (code, real_part (e1), real_part (e2)); + tree ieq = build_float_identity (code, imaginary_part (e1), imaginary_part (e2)); - tree result = build_call_expr (tmemcmp, 3, build_address (t1), - build_address (t2), size); - this->result_ = build_boolop (code, result, integer_zero_node); + if (code == EQ_EXPR) + this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq); + else + this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq); + } + else if (tb1->isfloating () && tb1->ty != Tvector) + { + tree e1 = d_save_expr (build_expr (e->e1)); + tree e2 = d_save_expr (build_expr (e->e2)); + this->result_ = build_float_identity (code, e1, e2); } else if (tb1->ty == Tstruct) { diff --git a/gcc/testsuite/gdc.dg/runnable.d b/gcc/testsuite/gdc.dg/runnable.d index ec172fae810..65c71e86292 100644 --- a/gcc/testsuite/gdc.dg/runnable.d +++ b/gcc/testsuite/gdc.dg/runnable.d @@ -1534,6 +1534,27 @@ void test286() assert(0); } +/******************************************/ +// https://bugzilla.gdcproject.org/show_bug.cgi?id=309 + +void test309() +{ + creal f1 = +0.0 + 0.0i; + creal f2 = +0.0 - 0.0i; + creal f3 = -0.0 + 0.0i; + creal f4 = +0.0 + 0.0i; + + assert(f1 !is f2); + assert(f1 !is f3); + assert(f2 !is f3); + assert(f1 is f4); + + assert(!(f1 is f2)); + assert(!(f1 is f3)); + assert(!(f2 is f3)); + assert(!(f1 !is f4)); +} + /******************************************/ void main() @@ -1571,6 +1592,7 @@ void main() test273(); test285(); test286(); + test309(); printf("Success!\n"); } -- 2.19.1