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.

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

gcc/d/ChangeLog:

	PR d/98921
	* dmd/MERGE: Merge upstream dmd 5e2a81d9c.
This commit is contained in:
Iain Buclaw 2021-02-02 00:52:49 +01:00
parent f7884fb176
commit 6a481021a6
4 changed files with 53 additions and 10 deletions

View 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.

View 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];

View 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);

View 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);