[erlang-bugs] erl_parse, different argument processing for "-module" and "-import"

Alexander Demidenko <>
Thu Jul 7 15:17:39 CEST 2011


Hi, friends!

Module erl_parse have different AST processing for "-module" and
"-include" directive.
This bug tested on erlang 13B03, 13B04 and 14B03.
Bug demonstration:

Erlang R13B03 (erts-5.7.4) [source] [64-bit] [smp:4:4] [rq:4]
[async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.7.4  (abort with ^G)
1> Str2AST = fun (S) -> {ok, Tokens, _} = erl_scan:string(S), {ok, R}
= erl_parse:parse_form(Tokens), R end.
#Fun<erl_eval.6.13229925>
2> AST1 = Str2AST("-import(m).").
{attribute,1,import,[m]}

Look at module name in result. You can see list of atoms: [m].
But they must be list only for complex module name (for example:
-import(namespace.m))
Continue...

3> {Tree, _} = erl_syntax_lib:mapfold(fun (T, Acc) -> {T, Acc} end, [], AST1).
{{tree,attribute,
       {attr,1,[],none},
       {attribute,{tree,atom,{attr,1,[],none},import},
                  [{tree,qualified_name,
                         {attr,0,[],none},
                         [{tree,atom,{attr,0,[],none},m}]}]}},
 []}
4> AST2 = erl_syntax:revert(Tree).
{attribute,1,import,m}
5> AST1 == AST2.
false

Ops, magic, inside AST2, module name is atom!
But if we try run example with "-module(m)", everything ok. We have
module name like atom in anyway.

6> AST3 = Str2AST("-module(m).").
{attribute,1,module,m}

Ok, now lets look at source of erl_parse:
Part of import processing (should be fixed):

build_attribute({atom,La,import}, Val) ->
    case Val of
    [Name] ->
        case package_segments(Name) of    % <--- Here we always take list
        error ->
            error_bad_decl(La, import);
        Module ->
            {attribute,La,import,Module}      % <--- as result we have
list of atom, like [module_name]
        end;
    [{atom,_Lm,Mod},ImpList] ->
        {attribute,La,import,{Mod,farity_list(ImpList)}};
    [Name, ImpList] ->
        case package_segments(Name) of
        error ->
            error_bad_decl(La, import);
        Module ->
            {attribute,La,import,{Module,farity_list(ImpList)}}
        end;
    _Other -> error_bad_decl(La, import)
    end;

Part of module processing (correct version):
build_attribute({atom,La,module}, Val) ->
    case Val of
    [{atom,_Lm,Module}] ->                    % <--- I think, we must
have same special case clause for 'import' version of
build_attribute()
        {attribute,La,module,Module};
    [{atom,_Lm,Module},ExpList] ->
        {attribute,La,module,{Module,var_list(ExpList)}};
    [Name] ->
        case package_segments(Name) of
        error ->
            error_bad_decl(La, module);
        Module ->
            {attribute,La,module,Module}
        end;
    [Name,ExpList] ->
        case package_segments(Name) of
        error ->
            error_bad_decl(La, module);
        Module ->
            {attribute,La,module,{Module,var_list(ExpList)}}
        end;
    _Other ->
        error_bad_decl(La, module)
    end;





--
---------------------------------------------
With best regards,
Alexander.


More information about the erlang-bugs mailing list