diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2020-08-03 22:35:38 +0200 |
---|---|---|
committer | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-08-17 15:07:29 -0300 |
commit | c0e64c95698d8b068572e9f4af55d6483749b614 (patch) | |
tree | 0ff32d911d4a2bcdad0db609d808842b285e3a17 | |
parent | afc8e9f8cfd40e4eed91389d4c1484f91375ef16 (diff) | |
download | gcc-c0e64c95698d8b068572e9f4af55d6483749b614.zip gcc-c0e64c95698d8b068572e9f4af55d6483749b614.tar.gz gcc-c0e64c95698d8b068572e9f4af55d6483749b614.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.
-rw-r--r-- | gcc/d/expr.cc | 12 | ||||
-rw-r--r-- | gcc/testsuite/gdc.dg/pr96429.d | 26 |
2 files changed, 38 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; diff --git a/gcc/testsuite/gdc.dg/pr96429.d b/gcc/testsuite/gdc.dg/pr96429.d new file mode 100644 index 0000000..af096e2 --- /dev/null +++ b/gcc/testsuite/gdc.dg/pr96429.d @@ -0,0 +1,26 @@ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96429 +// { dg-do compile } +// { dg-options "-fdump-tree-original" } +ptrdiff_t subbyte(byte* bp1, byte* bp2) +{ + // { dg-final { scan-tree-dump "bp1 - bp2;" "original" } } + return bp1 - bp2; +} + +ptrdiff_t subshort(short* sp1, short* sp2) +{ + // { dg-final { scan-tree-dump "\\\(sp1 - sp2\\\) /\\\[ex\\\] 2;" "original" } } + return sp1 - sp2; +} + +ptrdiff_t subint(int* ip1, int* ip2) +{ + // { dg-final { scan-tree-dump "\\\(ip1 - ip2\\\) /\\\[ex\\\] 4;" "original" } } + return ip1 - ip2; +} + +ptrdiff_t sublong(long* lp1, long* lp2) +{ + // { dg-final { scan-tree-dump "\\\(lp1 - lp2\\\) /\\\[ex\\\] 8;" "original" } } + return lp1 - lp2; +} |