Bug 6893 – Write of enum member represented with ubyte or ulong

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2011-11-05T04:05:00Z
Last change time
2013-08-24T02:36:53Z
Keywords
pull
Assigned to
nobody
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2011-11-05T04:05:46Z
import std.stdio; enum E1 : uint { A, B, C }; enum E2 : ubyte { A, B, C }; enum E3 : ulong { A, B, C }; void main() { writeln(E1.C); writeln(E2.C); writeln(E3.C); } Output dmd 2.057head: C  <error> Expected output: C C C
Comment #1 by andrej.mitrovich — 2012-12-02T10:35:38Z
First two are ok now but the 3rd has become a massive template instance error (2.061).
Comment #2 by hsteoh — 2013-08-22T17:21:19Z
The problem appears to be std.format.getNthInt, under "static if (isIntegral!...)": the code assumes that if a type is integral, it can be converted to int, but this is not true when the base type of the enum is ulong.
Comment #3 by hsteoh — 2013-08-22T17:31:41Z
Hmm actually, there appears to be a bug somewhere else. The spec shouldn't be spec.DYNAMIC at all, since the default spec for enums is "%s". So something went wrong before this point.
Comment #4 by andrej.mitrovich — 2013-08-22T17:33:31Z
(In reply to comment #3) > Hmm actually, there appears to be a bug somewhere else. The spec shouldn't be > spec.DYNAMIC at all, since the default spec for enums is "%s". So something > went wrong before this point. Last time I tried to fix this I lost my head in the formatting jungle. Good luck!
Comment #5 by hsteoh — 2013-08-22T17:45:59Z
Aha! I found the reason: getNthInt is called from a *compile-time* check, so even if the spec for enum is "%s", the compiler still has to compile this branch of the code. So the fix is for getNthInt to *statically* verify convertibility to int before attempting to call to!int.
Comment #6 by hsteoh — 2013-08-22T18:08:22Z
Argh. I wish bugzilla allowed editing of comments... What I meant was: getNthInt is called from inside a *runtime* if-condition that evaluates to false when the spec is "%s" and the argument is a ulong enum, but since this if-condition can only be checked at runtime, getNthInt must be able to compile in that case. Currently it doesn't compile because it assumes isIntegral!T means T can be implicitly converted to int, which is not true if the argument is a ulong (or a ulong enum). So the fix is to replace isIntegral with is(typeof(to!int(...))) so that at compile-time the compiler will hardcode the function to throw an exception when an invalid argument is given. (It won't actually throw at runtime if the if-condition in the caller evaluates to false at runtime.)
Comment #7 by hsteoh — 2013-08-22T18:11:31Z
Comment #8 by github-bugzilla — 2013-08-24T01:45:12Z
Commits pushed to master at https://github.com/D-Programming-Language/phobos https://github.com/D-Programming-Language/phobos/commit/b680614e571c52b45cef9288e15ec3df601828a3 Add unittest for issue 6893. https://github.com/D-Programming-Language/phobos/commit/cbc684a001e53e3f1fc95ef6caddb0c66095e2f0 Merge pull request #1504 from quickfur/bug6893 Issue 6893 - Write of enum member represented with ubyte or ulong