]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
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 01:34:25 +0000 (02:34 +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.

gcc/d/ChangeLog:

PR d/98921
* dmd/dmangle.c (Mangler::visit (TypeSArray *)): Use buf->print
  to format integer value.
(Mangler::visit (TypeIdentifier *)): Likewise.
(Mangler::toBuffer): Likewise.
(Mangler::visit (IntegerExp *)): Likewise.
(Mangler::visit (StringExp *)): Likewise.
(Mangler::visit (ArrayLiteralExp *)): Likewise.
(Mangler::visit (AssocArrayLiteralExp *)): Likewise.
(Mangler::visit (StructLiteralExp *)): Likewise.
* dmd/root/outbuffer.c (OutBuffer::print): New function.
* dmd/root/outbuffer.h (OutBuffer::print): Declare.

(cherry picked from commit 6a481021a65d6237b0c509a76fcd9c1f32c4558e)

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

index f41f6284dc515619c799104da34e3c11f8a9f0c1..a38ae4614e68d7a911d069cf74b7a294633851e7 100644 (file)
@@ -177,7 +177,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);
     }
@@ -275,7 +275,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)
@@ -397,7 +398,7 @@ public:
             s->error("excessive length %llu for symbol, possible recursive expansion?", len);
         else
         {
-            buf->printf("%llu", (ulonglong)len);
+            buf->print(len);
             buf->write(id, len);
         }
     }
@@ -615,9 +616,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)
@@ -739,7 +746,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->data + buf->offset, *pend = p + 2 * qlen;
              p < pend; p += 2, ++q)
@@ -755,7 +763,8 @@ public:
     void visit(ArrayLiteralExp *e)
     {
         size_t dim = e->elements ? e->elements->dim : 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);
@@ -765,7 +774,8 @@ public:
     void visit(AssocArrayLiteralExp *e)
     {
         size_t dim = e->keys->dim;
-        buf->printf("A%u", dim);
+        buf->writeByte('A');
+        buf->print(dim);
         for (size_t i = 0; i < dim; i++)
         {
             (*e->keys)[i]->accept(this);
@@ -776,7 +786,8 @@ public:
     void visit(StructLiteralExp *e)
     {
         size_t dim = e->elements ? e->elements->dim : 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 4f478e2306a019b4e795dadc1317ce74a0733b41..08562330724b76b04c72e395bba9c6fd316ef785 100644 (file)
@@ -325,6 +325,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 7c8cc7c6793b23176ecb839f2ae3754e626c6ff9..920f4d057217a33d986d6e401d1d3e8078ae80a7 100644 (file)
@@ -62,6 +62,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);