diff --git a/compiler/src/dmd/glue/toobj.d b/compiler/src/dmd/glue/toobj.d index a07b6f98d2de..64bb5e292078 100644 --- a/compiler/src/dmd/glue/toobj.d +++ b/compiler/src/dmd/glue/toobj.d @@ -119,7 +119,8 @@ void write_instance_pointers(Type type, Symbol* s, uint offset) return; Array!(ulong) data; - const ulong sz = getTypePointerBitmap(Loc.initial, type, data, global.errorSink); + ulong count; + const ulong sz = getTypePointerBitmap(Loc.initial, type, data, global.errorSink, count); if (sz == ulong.max) return; diff --git a/compiler/src/dmd/traits.d b/compiler/src/dmd/traits.d index 568fe0807789..2d9ff1bed605 100644 --- a/compiler/src/dmd/traits.d +++ b/compiler/src/dmd/traits.d @@ -99,10 +99,11 @@ private Dsymbol getDsymbolWithoutExpCtx(RootObject oarg) * t = type to generate pointer bitmap from * data = array forming the bitmap * eSink = error message sink + * count = returns the number of bits set in the bitmap (i.e. the number of pointers) * Returns: * size of the type `t` in bytes, ulong.max on error */ -ulong getTypePointerBitmap(Loc loc, Type t, ref Array!(ulong) data, ErrorSink eSink) +ulong getTypePointerBitmap(Loc loc, Type t, ref Array!(ulong) data, ErrorSink eSink, out ulong count) { auto tc = t.isTypeClass(); const ulong sz = (tc && !tc.sym.isInterfaceDeclaration()) @@ -133,6 +134,7 @@ ulong getTypePointerBitmap(Loc loc, Type t, ref Array!(ulong) data, ErrorSink eS { void setpointer(ulong off) { + count++; ulong ptroff = off / sz_size_t; data[cast(size_t)(ptroff / bitsPerElement)] |= 1L << (ptroff % bitsPerElement); } @@ -165,11 +167,14 @@ ulong getTypePointerBitmap(Loc loc, Type t, ref Array!(ulong) data, ErrorSink eS ulong nextsize = t.next.size(); if (nextsize == SIZE_INVALID) error = true; - ulong dim = t.dim.toInteger(); - for (ulong i = 0; i < dim; i++) + if (t.hasPointers) { - offset = arrayoff + i * nextsize; - visit(t.next); + ulong dim = t.dim.toInteger(); + for (ulong i = 0; i < dim; i++) + { + offset = arrayoff + i * nextsize; + visit(t.next); + } } offset = arrayoff; } @@ -286,6 +291,7 @@ ulong getTypePointerBitmap(Loc loc, Type t, ref Array!(ulong) data, ErrorSink eS * architecture). If set the corresponding memory might contain a pointer/reference. * * Returns: [T.sizeof, pointerbit0-31/63, pointerbit32/64-63/128, ...] + * OR: [T.sizeof] if the type contains no pointers */ private Expression pointerBitmap(TraitsExp e, ErrorSink eSink) { @@ -303,10 +309,18 @@ private Expression pointerBitmap(TraitsExp e, ErrorSink eSink) } Array!(ulong) data; - const ulong sz = getTypePointerBitmap(e.loc, t, data, eSink); + ulong count; + const ulong sz = getTypePointerBitmap(e.loc, t, data, eSink, count); if (sz == ulong.max) return ErrorExp.get(); + if (count == 0) + { + auto exps = new Expressions(1); + (*exps)[0] = new IntegerExp(e.loc, sz, Type.tsize_t); + return new ArrayLiteralExp(e.loc, Type.tsize_t.sarrayOf(1), exps); + } + auto exps = new Expressions(data.length + 1); (*exps)[0] = new IntegerExp(e.loc, sz, Type.tsize_t); // [0] is size in bytes of t foreach (size_t i; 1 .. exps.length) diff --git a/druntime/src/object.d b/druntime/src/object.d index 96fd06b59ebd..d1fb2a4a9fe3 100644 --- a/druntime/src/object.d +++ b/druntime/src/object.d @@ -3757,7 +3757,7 @@ template RTInfoImpl(size_t[] pointerBitmap) template RTInfo(T) { enum pointerBitmap = __traits(getPointerBitmap, T); - static if (pointerBitmap[1 .. $] == size_t[pointerBitmap.length - 1].init) + static if (pointerBitmap.length == 1) enum RTInfo = rtinfoNoPointers; else enum RTInfo = RTInfoImpl!(pointerBitmap).ptr;