[erlang-bugs] dialyzer false positive io_lib:fread
Kostis Sagonas
kostis@REDACTED
Sun Aug 11 00:20:05 CEST 2013
On 08/10/2013 07:11 AM, Chris King wrote:
> Hi,
>
> Re-sending this, as it seems (after a month checking the archive) that
> this mailing list silently rejects e-mails from non-subscribers?
> (There's no mention of this behavior in the listinfo page
> http://erlang.org/mailman/listinfo/erlang-bugs.)
>
>
> dialyzer produces a false positive when analyzing io_lib:fread with a ~a
> argument – it believes (erroneously) that the parsed value will be a
> string, when in fact it will be an atom. This does not occur with
> io:fread, or with io_lib:fread with an integer argument.
>
> The below test program exemplifies this; dialyzer claims that bugged/1
> cannot return, when in fact calling bugged("foo") returns normally in
> the interpreter.
>
> I would be glad to supply a patch but I haven't the slightest clue where
> to start looking (this seems like either an easy fix, in an "exceptions"
> list somewhere, or a complex fix deep inside dialyzer).
The behaviour you are experiencing is a side-effect of the type and spec
declarations that exist in modules io_lib and io_lib_fread (*)
(*) Aside: is there a really good reason why io_lib_fread is a separate
module with cyclic dependencies to io_lib and polluting the module name
space, instead of being part of io_lib?
In io_lib, the fread/2 function is defined as:
fread(Chars, Format) ->
io_lib_fread:fread(Chars, Format).
and in io_lib_fread the spec of fread/2 reads:
-spec fread(Format, String) -> Result when
Format :: string(),
String :: string(),
Result :: {'ok', InputList :: io_lib:chars(), LeftOverChars ::
string()}
...
where the io_lib:chars() type is defined as:
-type chars() :: [char() | chars()].
mentioning nowhere that the InputList also possibly contains atoms
instead of just chars(), i.e. short integers.
Note that the fact that the spec of io_lib:fread/2 reads:
-spec fread(Format, String) -> Result when
Format :: string(),
String :: string(),
Result :: {'ok', InputList :: [term()], LeftOverChars :: string()}
...
is irrelevant since dialyzer will take the strongest type information it
infers when spec declarations are too loose.
Anyway, I am not sure whether the intention of the library developer is
to document the possibility to return an atom list or not in that
position, so no patch from me either.
Hope this helps someone at OTP to fix this, possibly also folding the
io_lib_fread module into io_lib the process.
Kostis
More information about the erlang-bugs
mailing list