d: Fix junk in generated symbol on powerpc64-*-* [PR98921]
authorIain Buclaw <ibuclaw@gdcproject.org>
Mon, 1 Feb 2021 23:52:49 +0000 (00:52 +0100)
committerIain Buclaw <ibuclaw@gdcproject.org>
Tue, 2 Feb 2021 00:24:14 +0000 (01:24 +0100)
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.

Reviewed-on: https://github.com/dlang/dmd/pull/12174

gcc/d/ChangeLog:

PR d/98921
* dmd/MERGE: Merge upstream dmd 5e2a81d9c.

gcc/d/dmd/MERGE
gcc/d/dmd/dmangle.c
gcc/d/dmd/root/outbuffer.c
gcc/d/dmd/root/outbuffer.h

index 228eed838b239c2fd0b2927b06a48998d029ef2e..342871f9a1aa3659ea17f2eeb3226b13e842951e 100644 (file)
@@ -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.
index f6eee52afbf04ff19b79619e284168ad90ae62da..4a9a118ebba67b39a69d5d41dfd7138db477093c 100644 (file)
@@ -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];
index 8544697a3d5ff192238241c5d56633c5ba293f96..81c2e9018059d323bb265a81012f109e1999918d 100644 (file)
@@ -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);
index 2ff5ee9b09c28cd225b5df9ecfda4b715c91db69..da0d305aa5275efd38cb5d1652ca4e3f6b49eae5 100644 (file)
@@ -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);