Bug 16739 – switch ignores case

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
druntime
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2016-11-23T19:05:05Z
Last change time
2018-01-28T03:26:08Z
Assigned to
No Owner
Creator
Chris

Comments

Comment #0 by wendlec — 2016-11-23T19:05:05Z
The following switch statement ignores a case when there's a smart quote involved (and other characters like "`"). The behavior is identical with both DMD (v2.072.0 and earlier) and LDC. import std.array; import std.conv; import std.stdio; void main() { auto tokens = to!(dchar[][])(["D"d, "’"d, "Addario"d, "'"d]); // Or use this below: //~ dstring[] tokens = ["D"d, "’"d, "Addario"d, "'"d]; while (!tokens.empty) { switch (tokens[0]) { case "\u2019"d: writeln("Apostrophe smart " ~ tokens[0]); break; case "\u0027"d: writeln("Apostrophe straight " ~ tokens[0]); break; default: writeln("Other " ~ tokens[0]); break; } tokens = tokens[1..$]; } } Prints: Other D Apostrophe smart ’ Other Addario Other ' Expected: Other D Apostrophe smart ’ Other Addario Apostrophe straight ' <== expected cf. http://forum.dlang.org/post/[email protected]
Comment #1 by ag0aep6g — 2016-11-23T19:15:05Z
Simplified test case: ---- void main() { int result = 0; switch ("a"d) { case "\u0100"d: result = 1; break; case "a"d: result = 2; break; default: result = 3; break; } assert(result == 2); /* fails; result is 3 */ } ---- Seems to be problem with code points > 0xFF. Doesn't fail with "00FF"d instead of "0100"d. Also fails with wstrings. Doesn't fail with strings.
Comment #2 by schveiguy — 2016-11-23T21:34:18Z
Interesting find by ketmar in https://forum.dlang.org/post/[email protected] The binary search through the list of possible strings is flawed -- it uses memcmp to do the binary search, and so allows the endianness of the machine to mess with the results.
Comment #3 by ketmar — 2016-11-25T19:28:37Z
as i am incompatible with github ;-), anybody is, of course, free to take my hackfix and turn it into real fix (mostly by adding unittests, i guess). no credits required.
Comment #4 by ag0aep6g — 2018-01-27T18:39:48Z
Works for me now with 2.078.0. Pull request to add a test: https://github.com/dlang/dmd/pull/7793
Comment #5 by ag0aep6g — 2018-01-28T00:42:19Z
Apparently this was actually a Druntime bug, and it was fixed by https://github.com/dlang/druntime/pull/1952 New PR for the test: https://github.com/dlang/druntime/pull/2064
Comment #6 by github-bugzilla — 2018-01-28T03:26:08Z
Commits pushed to master at https://github.com/dlang/druntime https://github.com/dlang/druntime/commit/efc7377ec02c19377366bf9eb80ed7b3653b457c add test for issue 16739 - switch ignores case https://github.com/dlang/druntime/commit/2411c52cbc31693e0a46fa06fb592787c9634ef0 Merge pull request #2064 from aG0aep6G/16739 add test for issue 16739 - switch ignores case merged-on-behalf-of: Andrei Alexandrescu <[email protected]>