Bug 13471 – CTFE glitch when executing std.digest.crc.crc32Of() and checking the result with enforce(). (keyword: uninitialized variable)

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-09-13T22:34:32Z
Last change time
2019-05-23T07:22:42Z
Keywords
CTFE, diagnostic, pull
Assigned to
No Owner
Creator
Marco Leise
Depends on
19892

Comments

Comment #0 by Marco.Leise — 2014-09-13T22:34:32Z
This snipped shows some strange behavoir: import std.digest.crc; import std.exception; enum buggy1 = foo("Hello World!"); enum buggy2 = crc32Of("Hello World!"); ubyte[4] foo(string str) { ubyte[4] result = str.crc32Of(); enforce (result != (ubyte[4]).init, "this should not be thrown"); return result; } When we look at `buggy2` the error message is hinting four times at some uninitialized variable, although we don't know where exactly that is: main.d(5): Error: uninitialized variable 'value' cannot be returned from CTFE main.d(5): Error: uninitialized variable 'value' cannot be returned from CTFE main.d(5): Error: uninitialized variable 'value' cannot be returned from CTFE main.d(5): Error: uninitialized variable 'value' cannot be returned from CTFE Now in the case of `buggy1` we do the same inside foo(), but check the result in the next line. It shows that although CTFE knows it cannot complete the crc32Of() call it continues on with a default initialized `result`: /opt/dmd-2.066/import/std/bitmanip.d(1796): Error: Integer constant expression expected instead of void /opt/dmd-2.066/import/std/bitmanip.d(1796): Error: Integer constant expression expected instead of void /opt/dmd-2.066/import/std/bitmanip.d(1796): Error: Integer constant expression expected instead of void /opt/dmd-2.066/import/std/bitmanip.d(1796): Error: Integer constant expression expected instead of void /opt/dmd-2.066/import/std/exception.d(374): Error: Uncaught CTFE exception object.Exception("this should not be thrown") main.d(4): called from here: foo("Hello World!") [Reproducible at least on 2.065 and 2.066]
Comment #1 by k.hara.pg — 2015-01-20T07:47:59Z
Reduced test case. Switch the error messages by -version=check. enum buggy1 = foo("Hello World!"); ubyte[4] foo(string str) { uint _state = uint.max; ubyte[4] result = nativeToLittleEndian(~_state); version(check) { import std.exception; enforce(result != (ubyte[4]).init, "this should not be thrown"); } return result; } union EndianSwapper(T) { T value; ubyte[T.sizeof] array; } auto nativeToLittleEndian(T)(T val) { return nativeToLittleEndianImpl(val); } auto nativeToLittleEndianImpl(T)(T val) { EndianSwapper!T es = void; es.value = val; return es.array; }
Comment #2 by dlang-bot — 2019-05-22T21:27:15Z
@thewilsonator updated dlang/phobos pull request #6976 "Fix issue 13741: can't use crc at CTFE" fixing this issue: - Fix issue 13471: can't use crc at CTFE https://github.com/dlang/phobos/pull/6976
Comment #3 by dlang-bot — 2019-05-23T07:22:42Z
dlang/phobos pull request #6976 "Fix issue 13471: can't use crc at CTFE" was merged into master: - 516432d185bf4ace339f7e571f1b46894e8536aa by Nicholas Lindsay Wilson: Fix issue 13471: can't use crc at CTFE https://github.com/dlang/phobos/pull/6976