lfortran / lfortran

Official main repository for LFortran
https://lfortran.org/
Other
972 stars 158 forks source link

(PRIMA) Calling Type Declared subroutine with empty arguments fails #5500

Open jinangshah21 opened 4 days ago

jinangshah21 commented 4 days ago

MRE :

module my_module
contains
    subroutine cb(x)
    implicit none
    integer, intent(in), optional :: x(:)
    end subroutine cb
end module my_module

program test
    use my_module
    call temp(cb)

contains
    subroutine temp(call_back)
        implicit none
        procedure(cb) :: call_back
        logical :: terminate_var
        call call_back()   
    end subroutine temp
end program test

LFortran Error :

Internal Compiler Error: Unhandled exception
Traceback (most recent call last):
  Binary file "/mnt/c/lfortran/src/bin/lfortran", in _start
  File "/build/glibc-LcI20x/glibc-2.31/csu/../csu/libc-start.c", line 308, in __libc_start_main
  File "/mnt/c/lfortran/src/bin/lfortran.cpp", line 2689, in main
    return main_app(argc, argv);
  File "/mnt/c/lfortran/src/bin/lfortran.cpp", line 2628, in main_app(int, char**)
    err = compile_src_to_object_file(arg_file, tmp_o, false,
  File "/mnt/c/lfortran/src/bin/lfortran.cpp", line 1045, in (anonymous namespace)::compile_src_to_object_file(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, LCompilers::CompilerOptions&, LCompilers::PassManager&)
    res = fe.get_llvm3(*asr, lpm, diagnostics, infile);
  File "/mnt/c/lfortran/src/lfortran/fortran_evaluator.cpp", line 382, in LCompilers::FortranEvaluator::get_llvm3(LCompilers::ASR::TranslationUnit_t&, LCompilers::PassManager&, LCompilers::diag::Diagnostics&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
    compiler_options, run_fn, infile);
  File "/mnt/c/lfortran/src/libasr/codegen/asr_to_llvm.cpp", line 10377, in LCompilers::asr_to_llvm(LCompilers::ASR::TranslationUnit_t&, LCompilers::diag::Diagnostics&, llvm::LLVMContext&, Allocator&, LCompilers::PassManager&, LCompilers::CompilerOptions&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
    pass_manager.apply_passes(al, &asr, co.po, diagnostics);
  File "/mnt/c/lfortran/src/libasr/pass/pass_manager.h", line 403, in LCompilers::PassManager::apply_passes(Allocator&, LCompilers::ASR::TranslationUnit_t*, LCompilers::PassOptions&, LCompilers::diag::Diagnostics&)
    apply_passes(al, asr, _passes, pass_options, diagnostics);
  File "/mnt/c/lfortran/src/libasr/pass/pass_manager.h", line 180, in LCompilers::PassManager::apply_passes(Allocator&, LCompilers::ASR::TranslationUnit_t*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, LCompilers::PassOptions&, LCompilers::diag::Diagnostics&)
    _passes_db[passes[i]](al, *asr, pass_options);
  File "/mnt/c/lfortran/src/libasr/pass/transform_optional_argument_functions.cpp", line 580, in LCompilers::pass_transform_optional_argument_functions(Allocator&, LCompilers::ASR::TranslationUnit_t&, LCompilers::PassOptions const&)
    y.visit_TranslationUnit(unit);
  File "/mnt/c/lfortran/src/libasr/../libasr/asr.h", line 42975, in LCompilers::ASR::ASRPassBaseWalkVisitor<LCompilers::ReplaceSubroutineCallsWithOptionalArgumentsVisitor>::visit_TranslationUnit(LCompilers::ASR::TranslationUnit_t const&)
    this->visit_symbol(*a.second);
  File "/mnt/c/lfortran/src/libasr/../libasr/asr.h", line 5189, in LCompilers::ASR::BaseVisitor<LCompilers::ReplaceSubroutineCallsWithOptionalArgumentsVisitor>::visit_symbol(LCompilers::ASR::symbol_t const&)
    void visit_symbol(const symbol_t &b) { visit_symbol_t(b, self()); }
  File "/mnt/c/lfortran/src/libasr/../libasr/asr.h", line 4900, in void LCompilers::ASR::visit_symbol_t<LCompilers::ReplaceSubroutineCallsWithOptionalArgumentsVisitor>(LCompilers::ASR::symbol_t const&, LCompilers::ReplaceSubroutineCallsWithOptionalArgumentsVisitor&)
    case symbolType::Program: { v.visit_Program((const Program_t &)x); return; }
  File "/mnt/c/lfortran/src/libasr/../libasr/pass/pass_utils.h", line 311, in LCompilers::PassUtils::PassVisitor<LCompilers::ReplaceSubroutineCallsWithOptionalArgumentsVisitor>::visit_Program(LCompilers::ASR::Program_t const&)
    self().visit_Function(*s);
  File "/mnt/c/lfortran/src/libasr/../libasr/pass/pass_utils.h", line 335, in LCompilers::PassUtils::PassVisitor<LCompilers::ReplaceSubroutineCallsWithOptionalArgumentsVisitor>::visit_Function(LCompilers::ASR::Function_t const&)
    transform_stmts(xx.m_body, xx.n_body);
  File "/mnt/c/lfortran/src/libasr/../libasr/pass/pass_utils.h", line 280, in LCompilers::PassUtils::PassVisitor<LCompilers::ReplaceSubroutineCallsWithOptionalArgumentsVisitor>::transform_stmts(LCompilers::ASR::stmt_t**&, unsigned long&)
    self().visit_stmt(*m_body[i]);
  File "/mnt/c/lfortran/src/libasr/../libasr/asr.h", line 5206, in LCompilers::ASR::BaseVisitor<LCompilers::ReplaceSubroutineCallsWithOptionalArgumentsVisitor>::visit_stmt(LCompilers::ASR::stmt_t const&)
    void visit_stmt(const stmt_t &b) { visit_stmt_t(b, self()); }
  File "/mnt/c/lfortran/src/libasr/../libasr/asr.h", line 4952, in void LCompilers::ASR::visit_stmt_t<LCompilers::ReplaceSubroutineCallsWithOptionalArgumentsVisitor>(LCompilers::ASR::stmt_t const&, LCompilers::ReplaceSubroutineCallsWithOptionalArgumentsVisitor&)
    case stmtType::SubroutineCall: { v.visit_SubroutineCall((const SubroutineCall_t &)x); return; }
  File "/mnt/c/lfortran/src/libasr/pass/transform_optional_argument_functions.cpp", line 561, in LCompilers::ReplaceSubroutineCallsWithOptionalArgumentsVisitor::visit_SubroutineCall(LCompilers::ASR::SubroutineCall_t const&)
    if( !fill_new_args(new_args, al, x, current_scope, sym2optionalargidx) ) {
AssertFailed: i < x.n_args + is_method
jinangshah21 commented 4 days ago

In #5282 Type declared Subroutine was made supported, I think this is related to that.

Pranavchiku commented 4 days ago

Use the diff and then investigate pass_array_by_data.cpp

diff --git a/src/libasr/pass/transform_optional_argument_functions.cpp b/src/libasr/pass/transform_optional_argument_functions.cpp
index 1b40359c6..7904a4562 100644
--- a/src/libasr/pass/transform_optional_argument_functions.cpp
+++ b/src/libasr/pass/transform_optional_argument_functions.cpp
@@ -374,10 +374,13 @@ bool fill_new_args(Vec<ASR::call_arg_t>& new_args, Allocator& al,
     // `x.n_args` (as it only represents the "FunctionCall" arguments)
     // hence to adjust for that, `is_method` introduces an offset
     bool is_method = is_class_procedure && (!is_nopass);
+    std::cout<<"is_method: "<<is_method<<std::endl;
+    std::cout<<"x.n_args: "<<x.n_args<<std::endl;

     new_args.reserve(al, func->n_args);
     for( size_t i = 0, j = 0; j < func->n_args; j++, i++ ) {
-        LCOMPILERS_ASSERT(i < x.n_args + is_method);
+        std::cout<<"i: "<<i<<std::endl;
+        LCOMPILERS_ASSERT(i <= x.n_args + is_method);
         if( std::find(sym2optionalargidx[func_sym].begin(),
                       sym2optionalargidx[func_sym].end(), j)
             != sym2optionalargidx[func_sym].end() ) {