From: Iain Buclaw Date: Mon, 1 Feb 2021 23:52:49 +0000 (+0100) Subject: d: Fix junk in generated symbol on powerpc64-*-* [PR98921] X-Git-Tag: releases/gcc-10.3.0~330 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=38c2d9598b1b2f23b24f96fd8f58a89344b93609;p=thirdparty%2Fgcc.git d: Fix junk in generated symbol on powerpc64-*-* [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. 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) --- diff --git a/gcc/d/dmd/dmangle.c b/gcc/d/dmd/dmangle.c index f41f6284dc51..a38ae4614e68 100644 --- a/gcc/d/dmd/dmangle.c +++ b/gcc/d/dmd/dmangle.c @@ -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]; diff --git a/gcc/d/dmd/root/outbuffer.c b/gcc/d/dmd/root/outbuffer.c index 4f478e2306a0..08562330724b 100644 --- a/gcc/d/dmd/root/outbuffer.c +++ b/gcc/d/dmd/root/outbuffer.c @@ -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); diff --git a/gcc/d/dmd/root/outbuffer.h b/gcc/d/dmd/root/outbuffer.h index 7c8cc7c6793b..920f4d057217 100644 --- a/gcc/d/dmd/root/outbuffer.h +++ b/gcc/d/dmd/root/outbuffer.h @@ -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);