Bug 4958 – Floating point enums should check for total loss of precision
Status
RESOLVED
Resolution
FIXED
Severity
minor
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2010-09-30T00:22:00Z
Last change time
2012-04-20T10:15:58Z
Keywords
accepts-invalid, pull
Assigned to
yebblies
Creator
clugdbug
Comments
Comment #0 by clugdbug — 2010-09-30T00:22:51Z
This is a minor issue, but it has worried me ever since floating-point enums were introduced. This code compiles on 2.049:
enum FloatEnum : float { A = float.max/2, B, C }
// but this assert fails!
static assert(FloatEnum.A != FloatEnum.B);
It's an obscure trap, but it's easy to fix.
-----------------
PATCH: enum.c, EnumDeclaration::semantic(), line 234.
// Now set e to (elast + 1)
e = new AddExp(em->loc, elast, new IntegerExp(em->loc, 1, Type::tint32));
e = e->semantic(sce);
e = e->castTo(sce, elast->type);
e = e->optimize(WANTvalue | WANTinterpret);
+ // Check that e != elast (not always true for floats)
+ Expression *etest = new EqualExp(TOKequal, em->loc, e, elast);
+ etest = etest->semantic(sce);
+ etest = etest->optimize(WANTvalue | WANTinterpret);
+ if (etest->toInteger())
+ error("enum member %s has inexact value, due to loss of precision", em->toChars());
}
elast = e;
em->value = e;
2.059 Win32
PS E:\DigitalMars\dmd2\samples> rdmd -w --main bug.d
bug.d(3): Error: enum bug.FloatEnum enum member B has inexact value, due to loss of precision
bug.d(3): Error: enum bug.FloatEnum enum member C has inexact value, due to loss of precision
PS E:\DigitalMars\dmd2\samples>