rose-compiler / rose

Developed at Lawrence Livermore National Laboratory (LLNL), ROSE is an open source compiler infrastructure to build source-to-source program transformation and analysis tools for large-scale C (C89 and C98), C++ (C++98 and C++11), UPC, Fortran (77/95/2003), OpenMP, Java, Python and PHP applications.
http://rosecompiler.org
Other
606 stars 131 forks source link

Rose is not parsing Fortran 95 code #16

Closed thiagotei closed 5 years ago

thiagotei commented 7 years ago

I have these two modules that cannot be parsed by Rose. I used $ roseCompiler -rose:fortran95 ModDataStruct.f90 ModMPI.f90.

Module ModMPI

    USE ModDataStruct

CONTAINS

    subroutine SRTest1(region, gridID)
        type(t_region), pointer :: region
        integer :: gridID

        type(t_grid), pointer :: grid
        type(t_mixt_input), pointer :: input

        grid => region%grid(gridID)
        input => grid%input

    end subroutine SRTest1

End Module ModMPI
Module ModDataStruct

        TYPE t_region
            TYPE(t_grid), POINTER :: grid(:)
        END TYPE t_region

        TYPE t_grid
             Type (t_mixt_input), pointer :: input
        END TYPE t_grid

        TYPE t_mixt_input
             INTEGER :: periodicStorage
        END TYPE t_mixt_input

End Module ModDataStruct

The output that I get is:

WARNING: i != (qualifiedNameList.size() - 1) for LANL_POP code only! (i = 0 qualifiedNameList.size() = 2) 
Leaving trace_back_through_parent_scopes_lookup_member_variable_symbol(): 
roseCompiler: ../../../../src-git-03172017/src/frontend/OpenFortranParser_SAGE_Connection/fortran_support.C:2499: std::vector<SgSymbol*> trace_back_through_parent_scopes_lookup_member_variable_symbol(const std::vector<MultipartReferenceType>&, SgScopeStatement*): Assertion `i == (qualifiedNameList.size() - 1)' failed.
Aborted (core dumped)

I'm using the following Rose version:

$ roseCompiler --version    
ROSE (version: 0.9.8.8)
  --- using ROSE SCM version:
      --- ID: 5e9a2e22eeeb5584ad9005bd0fdc4bcc1cf38cfe
      --- Timestamp: 2017-03-14 22:21:14 UTC
  --- using EDG C/C++ front-end version: edg-4.9
  --- using OFP Fortran parser version: ofp-0.8.3
  --- using Boost version: 1.58.0 (/usr/workspace/wsa/bluenet/thiago/spack/opt/spack/chaos_5_x86_64_ib/gcc-5.3.0/boost-1.58.0-ljrsfqhlkzmutafcmo33pozt6esiycdf)
  --- using backend C compiler: gcc version: 5.3
  --- using backend C compiler path (as specified at configure time): gcc
  --- using backend C++ compiler: g++ version: 5.3
  --- using backend C++ compiler path (as specified at configure time): g++
  --- using original build tree path: /usr/workspace/wsa/bluenet/thiago/tools/build/rose/obj-git-03172017%gcc@5.3.0_autotools
  --- using instalation path: /g/g92/thiago/scratch/tools/rose-install-03172017%gcc@5.3.0_autotools
  --- using GNU readline version: unknown (readline is disabled)
  --- using libmagic version: unknown (libmagic is disabled)
  --- using yaml-cpp version: unknown (yaml-cpp is disabled)
  --- using lib-yices version: unknown (libyices is disabled)

Thanks,

Thiago

thiagotei commented 7 years ago

The problem arises likely from here fortran_support.C. This comment taken from the same file documents the issue: // Note that if this fails is it always because there was some case missed above (and so the structureScope was not set properly to permit the search to be continued resolve a name in a nested type or scope).

thiagotei commented 7 years ago

There are two errors found:

  1. It is getting the wrong scope for variables with the same name.
  2. Transforming pointers that are in derived types to functions.

Parsing the statement:

grid => region%grid(gridID)

It assumes that grid from region%grid is a function (since Fortran 2003 and OOP added to the standard, the rule can be ambiguous) because grid in SRTest1 is not an Array (it is a pointer to a type). This can be found here. It then removes the variable from the scope. Basically, it got the wrong variable on current scope (there are two variables with the same name in different scopes, it gets the closest one). Rose assumed the variable as a function and removed it from the SymbolTable. When the next statement comes along (input => grid_local%input) and wants to access the grid variable on the current scope it does not exist anymore. This log might help:

Symbol table has parent = 0x214bb50 = SgBasicBlock
Symbol    0: name = SRTest1 SgSymbol = 0x1a95000 = SgVariableSymbol type = 0x1f34880 = SgTypeVoid = SgTypeVoid get_symbol_basis() = 0x19900a0 = SgInitializedName = initialized_name_SRTest1
   Symbol's associated mangled name = _module___scope__SRTest1___Fb_v_Gb___Fe___L0R__scope____SgSS2____scope__SRTest1
Symbol    1: name = input SgSymbol = 0x1a94fd0 = SgVariableSymbol type = 0x1954b60 = SgPointerType = SgPointerType get_symbol_basis() = 0x198feb0 = SgInitializedName = initialized_name_input
   Symbol's associated mangled name = _module___scope__SRTest1___Fb_v_Gb___Fe___L0R__scope____SgSS2____scope__input
Symbol    2: name = grid SgSymbol = 0x1a94fa0 = SgVariableSymbol type = 0x1954ae8 = SgPointerType = SgPointerType get_symbol_basis() = 0x198fcc0 = SgInitializedName = initialized_name_grid
   Symbol's associated mangled name = _module___scope__SRTest1___Fb_v_Gb___Fe___L0R__scope____SgSS2____scope__grid
Leaving trace_back_through_parent_scopes_lookup_variable_symbol_but_do_not_build_variable(): variableSymbol = 0x1a94fa0 functionSymbol = (nil)
We might have to convert this from a scalar to a function = grid
variableType = SgPointerType
This is NOT an array type so it must be converted to a function call with argument (if arguments are required)
In R612 c_action_data_ref(): (variable built here) numPartRef = 2
qualifiedNameList name = region%grid
structureScope = 0x214bb50 = SgBasicBlock name = region
Output the symbol table at the structureScope (debugging i = 0):
Printing out the data within the symbol table (p_table = 0xcb9aa0,label = Output the symbol table at the current scope size = 2):
Internal static data: p_no_name: false p_name = grid
Symbol table has parent = 0x214bb50 = SgBasicBlock
Symbol    0: name = SRTest1 SgSymbol = 0x1a95000 = SgVariableSymbol type = 0x1f34880 = SgTypeVoid = SgTypeVoid get_symbol_basis() = 0x19900a0 = SgInitializedName = initialized_name_SRTest1
   Symbol's associated mangled name = _module___scope__SRTest1___Fb_v_Gb___Fe___L0R__scope____SgSS2____scope__SRTest1
Symbol    1: name = input SgSymbol = 0x1a94fd0 = SgVariableSymbol type = 0x1954b60 = SgPointerType = SgPointerType get_symbol_basis() = 0x198feb0 = SgInitializedName = initialized_name_input
   Symbol's associated mangled name = _module___scope__SRTest1___Fb_v_Gb___Fe___L0R__scope____SgSS2____scope__input`
tgamblin commented 7 years ago

@chunhualiao @justintoo any ideas on this?

thiagotei commented 7 years ago

I've looked at Fortran standard page 75 and this code follows the standard. As far as I understood, Rose action rules for the Fortran Parser are implemented incorrectly. The code

 grid => region%grid(gridID)

should be parsed first by region%grid and then the subscript. However, Rose is parsing first grid(gridID), then the region. That's also the reason why it removes grid from the wrong Symbol Table (it does not know the region at that point). The Fortran standard is very clear about that by stating:

R614 structure-component is data-ref In a structure-component, there shall be more than one part-ref and the rightmost part-ref shall be of the form part-name.

Where part-name does not have a subscript-list.

peihunglin commented 5 years ago

These two testing cases can be handled by ROSE (version: 0.9.11.112) now.