Uploaded image for project: 'Erlang/OTP'
  1. Erlang/OTP
  2. ERL-1476

xref erroneously claims M:behaviour_info/1 is undefined

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 24.0, 23.2
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None

      Description

      Upgrading from OTP-23.1.5 to OTP-23.2.3 caused our xref checks to fail, with complaints that calls to M:behaviour_info/1 are undefined, even though they provably are not. A git bisect identified the culprit:

      # first bad commit: [d74e9b343a8562aa2ffceb07ad44a1fa8fd45f48] Suppress xref output for unused export on behaviour's behaviour_info/1
      

      That's https://github.com/erlang/otp/pull/2752 aka https://bugs.erlang.org/browse/ERL-1353, which apparently wanted to prevent xref from reporting compiler-generated behaviour_info/1 functions as unused exports. Fine, but the implementation appears too crude, resulting in the problem reported here.

      Repeat-by:

      > cat a.erl
      -module(a).
      -export([foo/1]).
      -callback foo() -> ok.
      foo(Mod) -> Mod:foo().
      > cat b.erl
      -module(b).
      -export([bar/0]).
      bar() -> a:behaviour_info(callbacks).
      > cat x.erl
      -module(x).
      -export([ref/0]).
      ref() ->
        {ok, XREF} = xref:start([]),
        ok = xref:set_default(XREF, [{warnings, false}]),
        {ok, _} = xref:add_module(XREF, "a.beam"),
        {ok, _} = xref:add_module(XREF, "b.beam"),
        {ok, UndefCalls} = xref:analyze(XREF, undefined_function_calls),
        case UndefCalls of
          [] -> io:format(standard_io, "No undefined function calls\n", []);
          _ -> io:format(standard_io, "Undefined function calls: ~p\n", [UndefCalls])
        end.
      

      a implements a behaviour, b a test case, and x an xref wrapper. Let's run with OTP-23.2.3:

      > erlc +debug_info a.erl b.erl x.erl
      > erl -noshell -s x ref -s erlang halt
      Undefined function calls: [{{b,bar,0},{a,behaviour_info,1}}]
      

      This is is clearly wrong. The result is the same with current master. A re-run with OTP-23.1.5 shows the expected result:

      > otp.git/bin/erlc +debug_info a.erl b.erl x.erl
      > otp.git/bin/erl -noshell -s x ref -s erlang halt
      No undefined function calls
      

      I'll note that https://erlang.org/doc/design_principles/spec_proc.html#behaviours is pretty clear in implying that M:behaviour_info/1 is expected to exist.

        Attachments

          Activity

            People

            Assignee:
            hasse Hans Bolinder
            Reporter:
            Mikael Pettersson Mikael Pettersson
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: