Skip to content

Commit be616b4

Browse files
authored
[flang] Fix false errors in function result derived type checking (#156509)
When checking function result types that are implicitly declared at their pointer of use against the actual definitions of those functions (when available), be sure to use the type equivalence checker that allows for USE association and sequence type equivalence.
1 parent 4e36508 commit be616b4

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2695,9 +2695,16 @@ void ArraySpecVisitor::PostAttrSpec() {
26952695

26962696
FuncResultStack::~FuncResultStack() { CHECK(stack_.empty()); }
26972697

2698+
// True when either type is absent, or if they are both present and are
2699+
// equivalent for interface compatibility purposes.
26982700
static bool TypesMismatchIfNonNull(
26992701
const DeclTypeSpec *type1, const DeclTypeSpec *type2) {
2700-
return type1 && type2 && *type1 != *type2;
2702+
if (auto t1{evaluate::DynamicType::From(type1)}) {
2703+
if (auto t2{evaluate::DynamicType::From(type2)}) {
2704+
return !t1->IsEquivalentTo(*t2);
2705+
}
2706+
}
2707+
return false;
27012708
}
27022709

27032710
void FuncResultStack::CompleteFunctionResultType() {

flang/test/Semantics/global03.f90

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
! RUN: %python %S/test_errors.py %s %flang_fc1 -Werror
2+
! Catch discrepancies between implicit result types and a global definition,
3+
! allowing for derived types and type equivalence.
4+
5+
module m
6+
type t1
7+
integer n
8+
end type
9+
type t2
10+
real a
11+
end type
12+
type t3
13+
sequence
14+
integer n
15+
end type
16+
end
17+
18+
function xfunc1()
19+
use m
20+
type(t1) xfunc1
21+
xfunc1%n = 123
22+
end
23+
24+
function yfunc1()
25+
use m
26+
type(t1) yfunc1
27+
yfunc1%n = 123
28+
end
29+
30+
function zfunc1()
31+
type t3
32+
sequence
33+
integer n
34+
end type
35+
type(t3) zfunc1
36+
zfunc1%n = 123
37+
end
38+
39+
program main
40+
use m
41+
implicit type(t1) (x)
42+
implicit type(t2) (y)
43+
implicit type(t3) (z)
44+
print *, xfunc1() ! ok
45+
print *, xfunc2() ! ok
46+
!ERROR: Implicit declaration of function 'yfunc1' has a different result type than in previous declaration
47+
print *, yfunc1()
48+
print *, yfunc2()
49+
print *, zfunc1() ! ok
50+
print *, zfunc2() ! ok
51+
end
52+
53+
function xfunc2()
54+
use m
55+
type(t1) xfunc2
56+
xfunc2%n = 123
57+
end
58+
59+
function yfunc2()
60+
use m
61+
!ERROR: Function 'yfunc2' has a result type that differs from the implicit type it obtained in a previous reference
62+
type(t1) yfunc2
63+
yfunc2%n = 123
64+
end
65+
66+
function zfunc2()
67+
type t3
68+
sequence
69+
integer n
70+
end type
71+
type(t3) zfunc2
72+
zfunc2%n = 123
73+
end

0 commit comments

Comments
 (0)