aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2021-02-02 00:52:49 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2021-02-02 01:24:14 +0100
commit6a481021a65d6237b0c509a76fcd9c1f32c4558e (patch)
tree762ef9b75ff3acd769d3abd9a13c7fcb69047caf /gcc
parentf7884fb176128ca9299f5587815ce1908138b2f7 (diff)
downloadgcc-6a481021a65d6237b0c509a76fcd9c1f32c4558e.zip
gcc-6a481021a65d6237b0c509a76fcd9c1f32c4558e.tar.gz
gcc-6a481021a65d6237b0c509a76fcd9c1f32c4558e.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/dmangle.c29
-rw-r--r--gcc/d/dmd/root/outbuffer.c31
-rw-r--r--gcc/d/dmd/root/outbuffer.h1
4 files changed, 53 insertions, 10 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 228eed8..342871f 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 f6eee52..4a9a118 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 8544697..81c2e90 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 2ff5ee9..da0d305 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);