mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-29 08:31:13 +00:00
[flang] Handle type-bound procedures with alternate returns
If you specify a type-bound procedure with an alternate return, there will be no symbol associated with that dummy argument. In such cases, the compiler's list of dummy arguments will contain a nullptr. In our analysis of the PASS arguments of type-bound procedures, we were assuming that all dummy arguments had non-null symbols associated with them and were using that assumption to get the name of the dummy argument. This caused the compiler to try to dereference a nullptr. I fixed this by explicitly checking for a nullptr and, in such cases, emitting an error message. I also added tests that contain type-bound procedures with alternate returns in both legal and illegal constructs to ensure that semantic analysis is working for them. Differential Revision: https://reviews.llvm.org/D98430
This commit is contained in:
parent
051f2c144e
commit
868187df21
@ -1359,6 +1359,13 @@ void CheckHelper::CheckPassArg(
|
||||
context_.SetError(*interface);
|
||||
return;
|
||||
}
|
||||
Symbol *argSym{dummyArgs[0]};
|
||||
if (!argSym) {
|
||||
messages_.Say(interface->name(),
|
||||
"Cannot use an alternate return as the passed-object dummy "
|
||||
"argument"_err_en_US);
|
||||
return;
|
||||
}
|
||||
passName = dummyArgs[0]->name();
|
||||
}
|
||||
std::optional<int> passArgIndex{};
|
||||
|
@ -132,7 +132,7 @@ contains
|
||||
end subroutine
|
||||
end module m1
|
||||
|
||||
module t2
|
||||
module m2
|
||||
type parent
|
||||
real realField
|
||||
contains
|
||||
@ -147,7 +147,71 @@ module t2
|
||||
contains
|
||||
subroutine proc
|
||||
end subroutine
|
||||
end module t2
|
||||
end module m2
|
||||
|
||||
module m3
|
||||
type t
|
||||
contains
|
||||
procedure b
|
||||
end type
|
||||
contains
|
||||
!ERROR: Cannot use an alternate return as the passed-object dummy argument
|
||||
subroutine b(*)
|
||||
return 1
|
||||
end subroutine
|
||||
end module m3
|
||||
|
||||
module m4
|
||||
type t
|
||||
contains
|
||||
procedure b
|
||||
end type
|
||||
contains
|
||||
! Check to see that alternate returns work with default PASS arguments
|
||||
subroutine b(this, *)
|
||||
class(t) :: this
|
||||
return 1
|
||||
end subroutine
|
||||
end module m4
|
||||
|
||||
module m5
|
||||
type t
|
||||
contains
|
||||
!ERROR: Passed-object dummy argument 'passarg' of procedure 'b' must be of type 't' but is 'INTEGER(4)'
|
||||
procedure, pass(passArg) :: b
|
||||
end type
|
||||
contains
|
||||
subroutine b(*, passArg)
|
||||
integer :: passArg
|
||||
return 1
|
||||
end subroutine
|
||||
end module m5
|
||||
|
||||
module m6
|
||||
type t
|
||||
contains
|
||||
!ERROR: Passed-object dummy argument 'passarg' of procedure 'b' must be polymorphic because 't' is extensible
|
||||
procedure, pass(passArg) :: b
|
||||
end type
|
||||
contains
|
||||
subroutine b(*, passArg)
|
||||
type(t) :: passArg
|
||||
return 1
|
||||
end subroutine
|
||||
end module m6
|
||||
|
||||
module m7
|
||||
type t
|
||||
contains
|
||||
! Check to see that alternate returns work with PASS arguments
|
||||
procedure, pass(passArg) :: b
|
||||
end type
|
||||
contains
|
||||
subroutine b(*, passArg)
|
||||
class(t) :: passArg
|
||||
return 1
|
||||
end subroutine
|
||||
end module m7
|
||||
|
||||
program test
|
||||
use m1
|
||||
|
Loading…
Reference in New Issue
Block a user