Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix subroutine with nopass attribute #2904

Merged
merged 5 commits into from
Nov 26, 2023

Conversation

Shaikh-Ubaid
Copy link
Member

fixes #2898

Comment on lines 30 to 31
program class_13
use class_13_mod
implicit none
print *, "Ok"
end program
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not call, caller and test it with some input?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. I updated it with a simpler example that produces the same compile time error as in #2898 (comment) and also has assert statements. We test for both function and subroutine declared with nopass.

@@ -217,7 +217,7 @@ stmt
| Select(expr test, case_stmt* body, stmt* default)
| Stop(expr? code)
| Assert(expr test, expr? msg)
| SubroutineCall(symbol name, symbol? original_name, call_arg* args, expr? dt)
| SubroutineCall(symbol name, symbol? original_name, call_arg* args, expr? dt, bool nopass)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this attribute rather be at the function/method definition/declaration site, so in the symbol table?

It seems the SubroutineCall should always list things explicitly, no nopass here seems redundant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. I updated it.

@Shaikh-Ubaid Shaikh-Ubaid force-pushed the subroutine_nopass branch 2 times, most recently from 5c37444 to 6d73943 Compare November 25, 2023 19:07
@Shaikh-Ubaid
Copy link
Member Author

For the example in #2898 (comment), we get:

$ cat examples/expr2.f90 
module subtest

    type, abstract :: abstract_type
    contains
       procedure(integer_method), deferred, nopass :: integer_method
    end type abstract_type

    abstract interface
       subroutine integer_method(n)
          integer :: n
       end subroutine integer_method
    end interface

    type :: Wrapper
       class(abstract_type),  allocatable :: obj
    contains
       procedure :: caller
    end type Wrapper

 contains

    subroutine caller(self)
       class(Wrapper), intent(in)  :: self
       integer :: n
       call self%obj%integer_method(n)
    end subroutine caller

 end module subtest
$ gfortran integration_tests/class_13.f90 -c
$ lfortran_in_main integration_tests/class_13.f90 -c
Traceback (most recent call last):
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/bin/lfortran.cpp", line 2322
    return compile_to_object_file(arg_file, outfile, false,
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/bin/lfortran.cpp", line 917
    result = fe.get_asr2(input, lm, diagnostics);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/fortran_evaluator.cpp", line 253
    Result<ASR::TranslationUnit_t*> res2 = get_asr3(*ast, diagnostics);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/fortran_evaluator.cpp", line 275
    compiler_options.symtab_only, compiler_options);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/semantics/ast_to_asr.cpp", line 128
    if (res.ok) {
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/semantics/ast_body_visitor.cpp", line 3407
    b.is_body_visitor = true;
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/semantics/ast_body_visitor.cpp", line 142
    visit_ast(*x.m_items[i]);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/ast.h", line 4848
    void visit_ast(const ast_t &b) { visit_ast_t(b, self()); }
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/ast.h", line 4804
    case astType::unit: { v.visit_unit((const unit_t &)x); return; }
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/ast.h", line 4851
    void visit_mod(const mod_t &b) { visit_mod_t(b, self()); }
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/ast.h", line 4438
    case modType::BlockData: { v.visit_BlockData((const BlockData_t &)x); return; }
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/semantics/ast_body_visitor.cpp", line 1515
    transform_stmts(body, x.n_body, x.m_body);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/semantics/ast_body_visitor.cpp", line 113
    this->visit_stmt(*m_body[i]);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/ast.h", line 4894
    void visit_stmt(const stmt_t &b) { visit_stmt_t(b, self()); }
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/ast.h", line 4568
    case stmtType::Stop: { v.visit_Stop((const Stop_t &)x); return; }
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/semantics/ast_body_visitor.cpp", line 2838
    tmp = ASRUtils::make_SubroutineCall_t_util(al, x.base.base.loc,
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/libasr/asr_utils.h", line 4619
    Call_t_body(al, a_name, a_args, n_args, a_dt, cast_stmt, implicit_argument_casting);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/libasr/asr_utils.h", line 4458
    ASRUtils::type_get_past_pointer(func_type->m_arg_types[i + is_method]));
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/libasr/asr_utils.h", line 159
    if (ASR::is_a<ASR::Pointer_t>(*f)) {
  Binary file "/usr/lib/system/libsystem_platform.dylib", local address: 0x18042ea83
Segfault: Signal SIGSEGV (segmentation fault) received
$ lfortran integration_tests/class_13.f90 -c 
$

@Shaikh-Ubaid
Copy link
Member Author

Shaikh-Ubaid commented Nov 25, 2023

And for the test added in integration_tests, we get:

$ gfortran integration_tests/class_13.f90
$ ./a.out 
          10
          12
$ lfortran_in_main integration_tests/class_13.f90 
Traceback (most recent call last):
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/bin/lfortran.cpp", line 2357
    err = compile_to_object_file(arg_file, tmp_o, false,
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/bin/lfortran.cpp", line 917
    result = fe.get_asr2(input, lm, diagnostics);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/fortran_evaluator.cpp", line 253
    Result<ASR::TranslationUnit_t*> res2 = get_asr3(*ast, diagnostics);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/fortran_evaluator.cpp", line 275
    compiler_options.symtab_only, compiler_options);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/semantics/ast_to_asr.cpp", line 128
    if (res.ok) {
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/semantics/ast_body_visitor.cpp", line 3407
    b.is_body_visitor = true;
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/semantics/ast_body_visitor.cpp", line 142
    visit_ast(*x.m_items[i]);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/ast.h", line 4848
    void visit_ast(const ast_t &b) { visit_ast_t(b, self()); }
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/ast.h", line 4804
    case astType::unit: { v.visit_unit((const unit_t &)x); return; }
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/ast.h", line 4851
    void visit_mod(const mod_t &b) { visit_mod_t(b, self()); }
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/ast.h", line 4438
    case modType::BlockData: { v.visit_BlockData((const BlockData_t &)x); return; }
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/semantics/ast_body_visitor.cpp", line 1515
    transform_stmts(body, x.n_body, x.m_body);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/semantics/ast_body_visitor.cpp", line 113
    this->visit_stmt(*m_body[i]);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/ast.h", line 4894
    void visit_stmt(const stmt_t &b) { visit_stmt_t(b, self()); }
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/ast.h", line 4568
    case stmtType::Stop: { v.visit_Stop((const Stop_t &)x); return; }
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/lfortran/semantics/ast_body_visitor.cpp", line 2838
    tmp = ASRUtils::make_SubroutineCall_t_util(al, x.base.base.loc,
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/libasr/asr_utils.h", line 4619
    Call_t_body(al, a_name, a_args, n_args, a_dt, cast_stmt, implicit_argument_casting);
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/libasr/asr_utils.h", line 4458
    ASRUtils::type_get_past_pointer(func_type->m_arg_types[i + is_method]));
  File "/Users/ubaid/Desktop/OpenSource/lfortran_in_main/src/libasr/asr_utils.h", line 159
    if (ASR::is_a<ASR::Pointer_t>(*f)) {
  Binary file "/usr/lib/system/libsystem_platform.dylib", local address: 0x18042ea83
Segfault: Signal SIGSEGV (segmentation fault) received
$ lfortran integration_tests/class_13.f90 
10
12

@Shaikh-Ubaid
Copy link
Member Author

Ready.

@czgdp1807 czgdp1807 merged commit 55fd002 into lfortran:main Nov 26, 2023
20 checks passed
@Shaikh-Ubaid Shaikh-Ubaid deleted the subroutine_nopass branch November 26, 2023 04:32
@difference-scheme
Copy link

Thanks a lot for this! It got rid of many errors.

We're slowly but surely getting there with these nopass, deferred procedures. There's an edge case, similar to Issue #2880, that still fails, though. I've opened a separate issue for that: #2914.

@certik
Copy link
Contributor

certik commented Nov 26, 2023

Thank you @difference-scheme for reporting the bugs. We will get it all fixed one by one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Deferred type-bound subroutine with nopass attribute leads to LFortran core dump
4 participants