aboutsummaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2020-08-03 22:35:38 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2020-08-04 10:25:22 +0200
commit3a3fda119036f46bfa70e06e7c69e04e78040079 (patch)
treecc8009d15548d8e188c44e54d0d0ce100e0d0ddc /gcc/d
parent863de9321813f947018cc60b06ba163ddcfbb5f2 (diff)
downloadgcc-3a3fda119036f46bfa70e06e7c69e04e78040079.zip
gcc-3a3fda119036f46bfa70e06e7c69e04e78040079.tar.gz
gcc-3a3fda119036f46bfa70e06e7c69e04e78040079.tar.bz2
d: Fix PR96429: Pointer subtraction uses TRUNC_DIV_EXPR
gcc/d/ChangeLog: PR d/96429 * expr.cc (ExprVisitor::visit (BinExp*)): Use EXACT_DIV_EXPR for pointer diff expressions. gcc/testsuite/ChangeLog: PR d/96429 * gdc.dg/pr96429.d: New test.
Diffstat (limited to 'gcc/d')
-rw-r--r--gcc/d/expr.cc12
1 files changed, 12 insertions, 0 deletions
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 20ab49d..ac3d4aa 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -620,6 +620,18 @@ public:
break;
case TOKdiv:
+ /* Determine if the div expression is a lowered pointer diff operation.
+ The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'. */
+ if (MinExp *me = e->e1->isMinExp ())
+ {
+ if (me->e1->type->ty == Tpointer && me->e2->type->ty == Tpointer
+ && e->e2->op == TOKint64)
+ {
+ code = EXACT_DIV_EXPR;
+ break;
+ }
+ }
+
code = e->e1->type->isintegral ()
? TRUNC_DIV_EXPR : RDIV_EXPR;
break;