diff --git a/compiler/src/dmd/dstruct.d b/compiler/src/dmd/dstruct.d index ca9b63260c..59c33baf77 100644 --- a/compiler/src/dmd/dstruct.d +++ b/compiler/src/dmd/dstruct.d @@ -318,96 +318,6 @@ extern (C++) class StructDeclaration : AggregateDeclaration } } -/********************************** - * Determine if exp is all binary zeros. - * Params: - * exp = expression to check - * Returns: - * true if it's all binary 0 - */ -bool _isZeroInit(Expression exp) -{ - switch (exp.op) - { - case EXP.int64: - return exp.toInteger() == 0; - - case EXP.null_: - return true; - - case EXP.structLiteral: - { - auto sle = exp.isStructLiteralExp(); - if (sle.sd.isNested()) - return false; - const isCstruct = sle.sd.isCsymbol(); // C structs are default initialized to all zeros - foreach (i; 0 .. sle.sd.fields.length) - { - auto field = sle.sd.fields[i]; - if (field.type.size(field.loc)) - { - auto e = sle.elements && i < sle.elements.length ? (*sle.elements)[i] : null; - if (e ? !_isZeroInit(e) - : !isCstruct && !field.type.isZeroInit(field.loc)) - return false; - } - } - return true; - } - - case EXP.arrayLiteral: - { - auto ale = cast(ArrayLiteralExp)exp; - - const dim = ale.elements ? ale.elements.length : 0; - - if (ale.type.toBasetype().ty == Tarray) // if initializing a dynamic array - return dim == 0; - - foreach (i; 0 .. dim) - { - if (!_isZeroInit(ale[i])) - return false; - } - - /* Note that true is returned for all T[0] - */ - return true; - } - - case EXP.string_: - { - auto se = cast(StringExp)exp; - - if (se.type.toBasetype().ty == Tarray) // if initializing a dynamic array - return se.len == 0; - - foreach (i; 0 .. se.len) - { - if (se.getIndex(i) != 0) - return false; - } - return true; - } - - case EXP.vector: - { - auto ve = cast(VectorExp) exp; - return _isZeroInit(ve.e1); - } - - case EXP.float64: - case EXP.complex80: - { - import dmd.root.ctfloat : CTFloat; - return (exp.toReal() is CTFloat.zero) && - (exp.toImaginary() is CTFloat.zero); - } - - default: - return false; - } -} /*********************************************************** * Unions are a variation on structs. diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d index f3abfe83b4..bde34ac242 100644 --- a/compiler/src/dmd/dsymbolsem.d +++ b/compiler/src/dmd/dsymbolsem.d @@ -8315,6 +8315,97 @@ void finalizeSize(AggregateDeclaration ad) ad.accept(v); } +/********************************** + * Determine if exp is all binary zeros. + * Params: + * exp = expression to check + * Returns: + * true if it's all binary 0 + */ +bool _isZeroInit(Expression exp) +{ + switch (exp.op) + { + case EXP.int64: + return exp.toInteger() == 0; + + case EXP.null_: + return true; + + case EXP.structLiteral: + { + auto sle = exp.isStructLiteralExp(); + if (sle.sd.isNested()) + return false; + const isCstruct = sle.sd.isCsymbol(); // C structs are default initialized to all zeros + foreach (i; 0 .. sle.sd.fields.length) + { + auto field = sle.sd.fields[i]; + if (field.type.size(field.loc)) + { + auto e = sle.elements && i < sle.elements.length ? (*sle.elements)[i] : null; + if (e ? !_isZeroInit(e) + : !isCstruct && !field.type.isZeroInit(field.loc)) + return false; + } + } + return true; + } + + case EXP.arrayLiteral: + { + auto ale = cast(ArrayLiteralExp)exp; + + const dim = ale.elements ? ale.elements.length : 0; + + if (ale.type.toBasetype().ty == Tarray) // if initializing a dynamic array + return dim == 0; + + foreach (i; 0 .. dim) + { + if (!_isZeroInit(ale[i])) + return false; + } + + /* Note that true is returned for all T[0] + */ + return true; + } + + case EXP.string_: + { + auto se = cast(StringExp)exp; + + if (se.type.toBasetype().ty == Tarray) // if initializing a dynamic array + return se.len == 0; + + foreach (i; 0 .. se.len) + { + if (se.getIndex(i) != 0) + return false; + } + return true; + } + + case EXP.vector: + { + auto ve = cast(VectorExp) exp; + return _isZeroInit(ve.e1); + } + + case EXP.float64: + case EXP.complex80: + { + import dmd.root.ctfloat : CTFloat; + return (exp.toReal() is CTFloat.zero) && + (exp.toImaginary() is CTFloat.zero); + } + + default: + return false; + } +} + private extern(C++) class FinalizeSizeVisitor : Visitor { alias visit = Visitor.visit; diff --git a/compiler/src/dmd/e2ir.d b/compiler/src/dmd/e2ir.d index 916049b80e..a57780678c 100644 --- a/compiler/src/dmd/e2ir.d +++ b/compiler/src/dmd/e2ir.d @@ -37,7 +37,7 @@ import dmd.dmodule; import dmd.dscope; import dmd.dstruct; import dmd.dsymbol; -import dmd.dsymbolsem : include; +import dmd.dsymbolsem : include, _isZeroInit; import dmd.dtemplate; import dmd.expression; import dmd.expressionsem : fill;