Hi,

This is patch is a backport of r15-7071, with test included ad verbatim.

Since the introduction of `gdc.test/runnable/test23514.d', it's exposed
an incorrect compilation when adding a 64-bit constant to a link-time
address.  The current cast to `size_t' causes a loss of precision, which
can result in incorrect compilation.

Bootstrapped and regtested on x86_64-linux-gnu/-m32, committed to
releases/gcc-12.

Regards,
Iain.

---
        PR d/114434

gcc/d/ChangeLog:

        * expr.cc (ExprVisitor::visit (PtrExp *)): Get the offset as a
        dinteger_t rather than a size_t.
        (ExprVisitor::visit (SymOffExp *)): Likewise.

gcc/testsuite/ChangeLog:

        * gdc.test/runnable/test23514.d: New test.

(cherry picked from commit 9ab38952a2033d6d4a8e31c3c4d2ab1a25a406c6)
---
 gcc/d/expr.cc                               |  4 ++--
 gcc/testsuite/gdc.test/runnable/test23514.d | 13 +++++++++++++
 2 files changed, 15 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gdc.test/runnable/test23514.d

diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 7afd98975b1..c308a068fc1 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -1537,7 +1537,7 @@ public:
   void visit (PtrExp *e)
   {
     Type *tnext = NULL;
-    size_t offset;
+    dinteger_t offset;
     tree result;
 
     if (e->e1->op == EXP::add)
@@ -2115,7 +2115,7 @@ public:
   void visit (SymOffExp *e)
   {
     /* Build the address and offset of the symbol.  */
-    size_t soffset = e->isSymOffExp ()->offset;
+    dinteger_t soffset = e->isSymOffExp ()->offset;
     tree result = get_decl_tree (e->var);
     TREE_USED (result) = 1;
 
diff --git a/gcc/testsuite/gdc.test/runnable/test23514.d 
b/gcc/testsuite/gdc.test/runnable/test23514.d
new file mode 100644
index 00000000000..1ba7e218d52
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test23514.d
@@ -0,0 +1,13 @@
+// DISABLED: win64
+// https://issues.dlang.org/show_bug.cgi?id=23514
+
+// Note: this test is disabled on Win64 because of an issue with the Windows
+// MS-COFF backend causing it to fail.
+
+enum ulong offset = 0xFFFF_FFFF_0000_0000UL;
+
+void main()
+{
+    ulong voffset = offset;
+    assert((cast(ulong)&main + voffset) == (cast(ulong)&main + offset));
+}
-- 
2.43.0

Reply via email to