Skip to content

Commit a52d7f0

Browse files
authored
Moved the _isZeroInit function out from dstruct.d into dsymbolsem.d (dlang#21172)
1 parent b2926b6 commit a52d7f0

File tree

3 files changed

+92
-91
lines changed

3 files changed

+92
-91
lines changed

compiler/src/dmd/dstruct.d

Lines changed: 0 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -318,96 +318,6 @@ extern (C++) class StructDeclaration : AggregateDeclaration
318318
}
319319
}
320320

321-
/**********************************
322-
* Determine if exp is all binary zeros.
323-
* Params:
324-
* exp = expression to check
325-
* Returns:
326-
* true if it's all binary 0
327-
*/
328-
bool _isZeroInit(Expression exp)
329-
{
330-
switch (exp.op)
331-
{
332-
case EXP.int64:
333-
return exp.toInteger() == 0;
334-
335-
case EXP.null_:
336-
return true;
337-
338-
case EXP.structLiteral:
339-
{
340-
auto sle = exp.isStructLiteralExp();
341-
if (sle.sd.isNested())
342-
return false;
343-
const isCstruct = sle.sd.isCsymbol(); // C structs are default initialized to all zeros
344-
foreach (i; 0 .. sle.sd.fields.length)
345-
{
346-
auto field = sle.sd.fields[i];
347-
if (field.type.size(field.loc))
348-
{
349-
auto e = sle.elements && i < sle.elements.length ? (*sle.elements)[i] : null;
350-
if (e ? !_isZeroInit(e)
351-
: !isCstruct && !field.type.isZeroInit(field.loc))
352-
return false;
353-
}
354-
}
355-
return true;
356-
}
357-
358-
case EXP.arrayLiteral:
359-
{
360-
auto ale = cast(ArrayLiteralExp)exp;
361-
362-
const dim = ale.elements ? ale.elements.length : 0;
363-
364-
if (ale.type.toBasetype().ty == Tarray) // if initializing a dynamic array
365-
return dim == 0;
366-
367-
foreach (i; 0 .. dim)
368-
{
369-
if (!_isZeroInit(ale[i]))
370-
return false;
371-
}
372-
373-
/* Note that true is returned for all T[0]
374-
*/
375-
return true;
376-
}
377-
378-
case EXP.string_:
379-
{
380-
auto se = cast(StringExp)exp;
381-
382-
if (se.type.toBasetype().ty == Tarray) // if initializing a dynamic array
383-
return se.len == 0;
384-
385-
foreach (i; 0 .. se.len)
386-
{
387-
if (se.getIndex(i) != 0)
388-
return false;
389-
}
390-
return true;
391-
}
392-
393-
case EXP.vector:
394-
{
395-
auto ve = cast(VectorExp) exp;
396-
return _isZeroInit(ve.e1);
397-
}
398-
399-
case EXP.float64:
400-
case EXP.complex80:
401-
{
402-
import dmd.root.ctfloat : CTFloat;
403-
return (exp.toReal() is CTFloat.zero) &&
404-
(exp.toImaginary() is CTFloat.zero);
405-
}
406-
407-
default:
408-
return false;
409-
}
410-
}
411321

412322
/***********************************************************
413323
* Unions are a variation on structs.

compiler/src/dmd/dsymbolsem.d

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8315,6 +8315,97 @@ void finalizeSize(AggregateDeclaration ad)
83158315
ad.accept(v);
83168316
}
83178317

8318+
/**********************************
8319+
* Determine if exp is all binary zeros.
8320+
* Params:
8321+
* exp = expression to check
8322+
* Returns:
8323+
* true if it's all binary 0
8324+
*/
8325+
bool _isZeroInit(Expression exp)
8326+
{
8327+
switch (exp.op)
8328+
{
8329+
case EXP.int64:
8330+
return exp.toInteger() == 0;
8331+
8332+
case EXP.null_:
8333+
return true;
8334+
8335+
case EXP.structLiteral:
8336+
{
8337+
auto sle = exp.isStructLiteralExp();
8338+
if (sle.sd.isNested())
8339+
return false;
8340+
const isCstruct = sle.sd.isCsymbol(); // C structs are default initialized to all zeros
8341+
foreach (i; 0 .. sle.sd.fields.length)
8342+
{
8343+
auto field = sle.sd.fields[i];
8344+
if (field.type.size(field.loc))
8345+
{
8346+
auto e = sle.elements && i < sle.elements.length ? (*sle.elements)[i] : null;
8347+
if (e ? !_isZeroInit(e)
8348+
: !isCstruct && !field.type.isZeroInit(field.loc))
8349+
return false;
8350+
}
8351+
}
8352+
return true;
8353+
}
8354+
8355+
case EXP.arrayLiteral:
8356+
{
8357+
auto ale = cast(ArrayLiteralExp)exp;
8358+
8359+
const dim = ale.elements ? ale.elements.length : 0;
8360+
8361+
if (ale.type.toBasetype().ty == Tarray) // if initializing a dynamic array
8362+
return dim == 0;
8363+
8364+
foreach (i; 0 .. dim)
8365+
{
8366+
if (!_isZeroInit(ale[i]))
8367+
return false;
8368+
}
8369+
8370+
/* Note that true is returned for all T[0]
8371+
*/
8372+
return true;
8373+
}
8374+
8375+
case EXP.string_:
8376+
{
8377+
auto se = cast(StringExp)exp;
8378+
8379+
if (se.type.toBasetype().ty == Tarray) // if initializing a dynamic array
8380+
return se.len == 0;
8381+
8382+
foreach (i; 0 .. se.len)
8383+
{
8384+
if (se.getIndex(i) != 0)
8385+
return false;
8386+
}
8387+
return true;
8388+
}
8389+
8390+
case EXP.vector:
8391+
{
8392+
auto ve = cast(VectorExp) exp;
8393+
return _isZeroInit(ve.e1);
8394+
}
8395+
8396+
case EXP.float64:
8397+
case EXP.complex80:
8398+
{
8399+
import dmd.root.ctfloat : CTFloat;
8400+
return (exp.toReal() is CTFloat.zero) &&
8401+
(exp.toImaginary() is CTFloat.zero);
8402+
}
8403+
8404+
default:
8405+
return false;
8406+
}
8407+
}
8408+
83188409
private extern(C++) class FinalizeSizeVisitor : Visitor
83198410
{
83208411
alias visit = Visitor.visit;

compiler/src/dmd/e2ir.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import dmd.dmodule;
3737
import dmd.dscope;
3838
import dmd.dstruct;
3939
import dmd.dsymbol;
40-
import dmd.dsymbolsem : include;
40+
import dmd.dsymbolsem : include, _isZeroInit;
4141
import dmd.dtemplate;
4242
import dmd.expression;
4343
import dmd.expressionsem : fill;

0 commit comments

Comments
 (0)