diff --git a/compiler/src/dmd/toobj.d b/compiler/src/dmd/toobj.d index 0481317aa0..5bdb966e72 100644 --- a/compiler/src/dmd/toobj.d +++ b/compiler/src/dmd/toobj.d @@ -36,6 +36,7 @@ import dmd.dstruct; import dmd.dsymbol; import dmd.dtemplate; import dmd.errors; +import dmd.errorsink; import dmd.expression; import dmd.func; import dmd.globals; @@ -248,18 +249,18 @@ void write_instance_pointers(Type type, Symbol *s, uint offset) return; Array!(ulong) data; - ulong sz = getTypePointerBitmap(Loc.initial, type, &data); + const ulong sz = getTypePointerBitmap(Loc.initial, type, data, global.errorSink); if (sz == ulong.max) return; const bytes_size_t = cast(size_t)Type.tsize_t.size(Loc.initial); const bits_size_t = bytes_size_t * 8; auto words = cast(size_t)(sz / bytes_size_t); - for (size_t i = 0; i < data.length; i++) + foreach (i, const element; data[]) { size_t bits = words < bits_size_t ? words : bits_size_t; - for (size_t b = 0; b < bits; b++) - if (data[i] & (1L << b)) + foreach (size_t b; 0 .. bits) + if (element & (1L << b)) { auto off = cast(uint) ((i * bits_size_t + b) * bytes_size_t); objmod.write_pointerRef(s, off + offset); diff --git a/compiler/src/dmd/traits.d b/compiler/src/dmd/traits.d index 050d650009..0acadbb460 100644 --- a/compiler/src/dmd/traits.d +++ b/compiler/src/dmd/traits.d @@ -32,6 +32,7 @@ import dmd.dsymbol; import dmd.dsymbolsem; import dmd.dtemplate; import dmd.errors; +import dmd.errorsink; import dmd.expression; import dmd.expressionsem; import dmd.func; @@ -92,44 +93,50 @@ private Dsymbol getDsymbolWithoutExpCtx(RootObject oarg) } /** - * get an array of size_t values that indicate possible pointer words in memory - * if interpreted as the type given as argument - * Returns: the size of the type in bytes, ulong.max on error + * Fill an array of target size_t values that indicate possible pointer words in memory + * if interpreted as the type given as argument. + * One bit in the array per pointer-sized piece of memory + * Params: + * loc = location for error messages + * t = type to generate pointer bitmap from + * data = array forming the bitmap + * eSink = error message sink + * Returns: + * size of the type `t` in bytes, ulong.max on error */ -ulong getTypePointerBitmap(Loc loc, Type t, Array!(ulong)* data) +ulong getTypePointerBitmap(Loc loc, Type t, ref Array!(ulong) data, ErrorSink eSink) { - ulong sz; auto tc = t.isTypeClass(); - if (tc && !tc.sym.isInterfaceDeclaration()) - sz = tc.sym.AggregateDeclaration.size(loc); - else - sz = t.size(loc); + const ulong sz = (tc && !tc.sym.isInterfaceDeclaration()) + ? tc.sym.AggregateDeclaration.size(loc) + : t.size(loc); if (sz == SIZE_INVALID) return ulong.max; - const sz_size_t = Type.tsize_t.size(loc); + const sz_size_t = Type.tsize_t.size(loc); // size of target's size_t + assert(sz_size_t <= ulong.sizeof); if (sz > sz.max - sz_size_t) { - error(loc, "size overflow for type `%s`", t.toChars()); + eSink.error(loc, "size overflow for type `%s`", t.toChars()); return ulong.max; } - ulong bitsPerWord = sz_size_t * 8; - ulong cntptr = (sz + sz_size_t - 1) / sz_size_t; - ulong cntdata = (cntptr + bitsPerWord - 1) / bitsPerWord; + const ulong bitsPerElement = sz_size_t * 8; // bits used in each array element + const ulong cntptr = (sz + sz_size_t - 1) / sz_size_t; // pointers have same size as sz_size_t + const ulong length = (cntptr + bitsPerElement - 1) / bitsPerElement; // a bit per pointer - data.setDim(cast(size_t)cntdata); + data.setDim(cast(size_t)length); data.zero(); ulong offset; - bool error; + bool error; // sticky error indicator void visit(Type t) { void setpointer(ulong off) { ulong ptroff = off / sz_size_t; - (*data)[cast(size_t)(ptroff / (8 * sz_size_t))] |= 1L << (ptroff % (8 * sz_size_t)); + data[cast(size_t)(ptroff / bitsPerElement)] |= 1L << (ptroff % bitsPerElement); } void visitType(Type t) @@ -282,28 +289,28 @@ ulong getTypePointerBitmap(Loc loc, Type t, Array!(ulong)* data) * * Returns: [T.sizeof, pointerbit0-31/63, pointerbit32/64-63/128, ...] */ -private Expression pointerBitmap(TraitsExp e) +private Expression pointerBitmap(TraitsExp e, ErrorSink eSink) { if (!e.args || e.args.length != 1) { - error(e.loc, "a single type expected for trait pointerBitmap"); + eSink.error(e.loc, "a single type expected for trait pointerBitmap"); return ErrorExp.get(); } Type t = getType((*e.args)[0]); if (!t) { - error(e.loc, "`%s` is not a type", (*e.args)[0].toChars()); + eSink.error(e.loc, "`%s` is not a type", (*e.args)[0].toChars()); return ErrorExp.get(); } Array!(ulong) data; - ulong sz = getTypePointerBitmap(e.loc, t, &data); + const ulong sz = getTypePointerBitmap(e.loc, t, data, eSink); if (sz == ulong.max) return ErrorExp.get(); auto exps = new Expressions(data.length + 1); - (*exps)[0] = new IntegerExp(e.loc, sz, Type.tsize_t); + (*exps)[0] = new IntegerExp(e.loc, sz, Type.tsize_t); // [0] is size in bytes of t foreach (size_t i; 1 .. exps.length) (*exps)[i] = new IntegerExp(e.loc, data[cast(size_t) (i - 1)], Type.tsize_t); @@ -1871,7 +1878,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) } if (e.ident == Id.getPointerBitmap) { - return pointerBitmap(e); + return pointerBitmap(e, global.errorSink); } if (e.ident == Id.initSymbol) {