[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
This commit is contained in:
Johannes Pfau 2019-01-20 12:15:47 +00:00 committed by Iain Buclaw
parent a766ecb0d4
commit 70d87497e7
4 changed files with 59 additions and 5 deletions

View File

@ -1,3 +1,8 @@
2019-01-20 Johannes Pfau <johannespfau@gmail.com>
* expr.cc (build_float_identity): New function.
(ExprVisitor::visit(IdentityExp)): Add support for complex types.
2019-01-16 Iain Buclaw <ibuclaw@gdcproject.org>
PR d/87824

View File

@ -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)
{

View File

@ -1,3 +1,7 @@
2019-01-20 Johannes Pfau <johannespfau@gmail.com>
* gdc.dg/runnable.d: Add tests for comparing complex types.
2019-01-20 Kewen Lin <linkw@gcc.gnu.org>
* gcc.target/powerpc/altivec_vld_vst_addr.c: Remove, split into

View File

@ -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");
}