diff mbox series

[committed] d: Fix junk in generated symbol on powerpc64-*-* (PR98921)

Message ID 20210202015733.683134-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Fix junk in generated symbol on powerpc64-*-* (PR98921) | expand

Commit Message

Iain Buclaw Feb. 2, 2021, 1:57 a.m. UTC
Hi,

This patch merges the D front-end implementation with upstream dmd
5e2a81d9c, fixing PR98921.  This adds a special formatter to OutBuffer
to handle formatted printing of integers, a common case.  The
replacement is faster and safer.

In dmangle.c, it also gets rid of a number of problematic casts, as seen
on powerpc64 targets.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and
on powerpc64le-linux-gnu.  Committed to mainline, and backported to the
releases/gcc-10 and gcc-9 branches.

Regards,
Iain.

---
gcc/d/ChangeLog:

	PR d/98921
	* dmd/MERGE: Merge upstream dmd 5e2a81d9c.
---
 gcc/d/dmd/MERGE            |  2 +-
 gcc/d/dmd/dmangle.c        | 29 ++++++++++++++++++++---------
 gcc/d/dmd/root/outbuffer.c | 31 +++++++++++++++++++++++++++++++
 gcc/d/dmd/root/outbuffer.h |  1 +
 4 files changed, 53 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 228eed838b2..342871f9a1a 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@ 
-609c3ce2d5d5d8a3dc4ba12c5e6e1100873f9ed1
+5e2a81d9cbcd653d9eed52344d664e72ba1355bc
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/dmangle.c b/gcc/d/dmd/dmangle.c
index f6eee52afbf..4a9a118ebba 100644
--- a/gcc/d/dmd/dmangle.c
+++ b/gcc/d/dmd/dmangle.c
@@ -279,7 +279,7 @@  public:
     {
         visit((Type *)t);
         if (t->dim)
-            buf->printf("%llu", t->dim->toInteger());
+            buf->print(t->dim->toInteger());
         if (t->next)
             visitWithMask(t->next, t->mod);
     }
@@ -377,7 +377,8 @@  public:
         visit((Type *)t);
         const char *name = t->ident->toChars();
         size_t len = strlen(name);
-        buf->printf("%u%s", (unsigned)len, name);
+        buf->print(len);
+        buf->writestring(name);
     }
 
     void visit(TypeEnum *t)
@@ -493,7 +494,7 @@  public:
             s->error("excessive length %llu for symbol, possible recursive expansion?", buf->length() + len);
         else
         {
-            buf->printf("%llu", (ulonglong)len);
+            buf->print(len);
             buf->write(id, len);
         }
     }
@@ -822,9 +823,15 @@  public:
     void visit(IntegerExp *e)
     {
         if ((sinteger_t)e->value < 0)
-            buf->printf("N%lld", -e->value);
+        {
+            buf->writeByte('N');
+            buf->print(-e->value);
+        }
         else
-            buf->printf("i%lld",  e->value);
+        {
+            buf->writeByte('i');
+            buf->print(e->value);
+        }
     }
 
     void visit(RealExp *e)
@@ -946,7 +953,8 @@  public:
         }
         buf->reserve(1 + 11 + 2 * qlen);
         buf->writeByte(m);
-        buf->printf("%d_", (int)qlen); // nbytes <= 11
+        buf->print(qlen);
+        buf->writeByte('_');    // nbytes <= 11
 
         for (utf8_t *p = (utf8_t *)buf->slice().ptr + buf->length(), *pend = p + 2 * qlen;
              p < pend; p += 2, ++q)
@@ -962,7 +970,8 @@  public:
     void visit(ArrayLiteralExp *e)
     {
         size_t dim = e->elements ? e->elements->length : 0;
-        buf->printf("A%u", dim);
+        buf->writeByte('A');
+        buf->print(dim);
         for (size_t i = 0; i < dim; i++)
         {
             e->getElement(i)->accept(this);
@@ -972,7 +981,8 @@  public:
     void visit(AssocArrayLiteralExp *e)
     {
         size_t dim = e->keys->length;
-        buf->printf("A%u", dim);
+        buf->writeByte('A');
+        buf->print(dim);
         for (size_t i = 0; i < dim; i++)
         {
             (*e->keys)[i]->accept(this);
@@ -983,7 +993,8 @@  public:
     void visit(StructLiteralExp *e)
     {
         size_t dim = e->elements ? e->elements->length : 0;
-        buf->printf("S%u", dim);
+        buf->writeByte('S');
+        buf->print(dim);
         for (size_t i = 0; i < dim; i++)
         {
             Expression *ex = (*e->elements)[i];
diff --git a/gcc/d/dmd/root/outbuffer.c b/gcc/d/dmd/root/outbuffer.c
index 8544697a3d5..81c2e901805 100644
--- a/gcc/d/dmd/root/outbuffer.c
+++ b/gcc/d/dmd/root/outbuffer.c
@@ -319,6 +319,37 @@  void OutBuffer::printf(const char *format, ...)
     va_end(ap);
 }
 
+/**************************************
+ * Convert `u` to a string and append it to the buffer.
+ * Params:
+ *  u = integral value to append
+ */
+void OutBuffer::print(unsigned long long u)
+{
+    unsigned long long value = u;
+    char buf[20];
+    const unsigned radix = 10;
+
+    size_t i = sizeof(buf);
+    do
+    {
+        if (value < radix)
+        {
+            unsigned char x = (unsigned char)value;
+            buf[--i] = (char)(x + '0');
+            break;
+        }
+        else
+        {
+            unsigned char x = (unsigned char)(value % radix);
+            value = value / radix;
+            buf[--i] = (char)(x + '0');
+        }
+    } while (value);
+
+    write(buf + i, sizeof(buf) - i);
+}
+
 void OutBuffer::bracket(char left, char right)
 {
     reserve(2);
diff --git a/gcc/d/dmd/root/outbuffer.h b/gcc/d/dmd/root/outbuffer.h
index 2ff5ee9b09c..da0d305aa52 100644
--- a/gcc/d/dmd/root/outbuffer.h
+++ b/gcc/d/dmd/root/outbuffer.h
@@ -61,6 +61,7 @@  public:
     void fill0(size_t nbytes);
     void vprintf(const char *format, va_list args);
     void printf(const char *format, ...);
+    void print(unsigned long long u);
     void bracket(char left, char right);
     size_t bracket(size_t i, const char *left, size_t j, const char *right);
     void spread(size_t offset, size_t nbytes);