diff options
author | Johannes Pfau <johannespfau@gmail.com> | 2019-01-20 12:15:47 +0000 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gcc.gnu.org> | 2019-01-20 12:15:47 +0000 |
commit | 70d87497e760dca94ef78e4e936f6d461f36e80d (patch) | |
tree | 7bbddd4a30ab412c00835963159a9d625f2498d0 /gcc/d/expr.cc | |
parent | a766ecb0d488624c0289620785ffe4e2d5cc9971 (diff) | |
download | gcc-70d87497e760dca94ef78e4e936f6d461f36e80d.zip gcc-70d87497e760dca94ef78e4e936f6d461f36e80d.tar.gz gcc-70d87497e760dca94ef78e4e936f6d461f36e80d.tar.bz2 |
[D] Fix IdentityExp comparison for complex floats.
gcc/d/ChangeLog:
2019-01-20 Johannes Pfau <johannespfau@gmail.com>
* expr.cc (build_float_identity): New function.
(ExprVisitor::visit(IdentityExp)): Add support for complex types.
gcc/testsuite/ChangeLog:
2019-01-20 Johannes Pfau <johannespfau@gmail.com>
* gdc.dg/runnable.d: Add tests for comparing complex types.
From-SVN: r268103
Diffstat (limited to 'gcc/d/expr.cc')
-rw-r--r-- | gcc/d/expr.cc | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 15754a1..a1f7c26 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -43,6 +43,20 @@ along with GCC; see the file COPYING3. If not see #include "d-tree.h" +/* Build a floating-point identity comparison between T1 and T2, ignoring any + excessive padding in the type. CODE is EQ_EXPR or NE_EXPR comparison. */ + +static tree +build_float_identity (tree_code code, tree t1, tree t2) +{ + 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. All visit methods accept one parameter E, which holds the frontend AST @@ -282,12 +296,21 @@ public: 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); + if (!tb1->iscomplex ()) + this->result_ = build_float_identity (code, t1, t2); + else + { + /* Compare the real and imaginary parts separately. */ + tree req = build_float_identity (code, real_part (t1), + real_part (t2)); + tree ieq = build_float_identity (code, imaginary_part (t1), + imaginary_part (t2)); - 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->ty == Tstruct) { |