Skip to content

Commit 79670f1

Browse files
authored
[flang] Improve scan for dummy argument type declarations (#172706)
We can handle a forward reference to an explicitly typed integer dummy argument when its name appears in a specification expression, rather than applying the active implicit typing rules, so long as the explicit type declaration statement has a literal constant kind number. Extend this to also accept INTEGER(int_ptr_kind()) or other function reference without an actual argument.
1 parent bc99ce0 commit 79670f1

File tree

8 files changed

+33
-17
lines changed

8 files changed

+33
-17
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7565,12 +7565,14 @@ void DeclarationVisitor::SetType(
75657565
} else if (HadForwardRef(symbol)) {
75667566
// error recovery after use of host-associated name
75677567
} else if (!symbol.test(Symbol::Flag::Implicit)) {
7568-
SayWithDecl(
7569-
name, symbol, "The type of '%s' has already been declared"_err_en_US);
7568+
SayWithDecl(name, symbol,
7569+
"The type of '%s' has already been declared as %s"_err_en_US,
7570+
prevType->AsFortran());
75707571
context().SetError(symbol);
75717572
} else if (type != *prevType) {
75727573
SayWithDecl(name, symbol,
7573-
"The type of '%s' has already been implicitly declared"_err_en_US);
7574+
"The type of '%s' has already been implicitly declared as %s"_err_en_US,
7575+
prevType->AsFortran());
75747576
context().SetError(symbol);
75757577
} else {
75767578
symbol.set(Symbol::Flag::Implicit, false);
@@ -9710,12 +9712,20 @@ void ResolveNamesVisitor::EarlyDummyTypeDeclaration(
97109712
const parser::Statement<common::Indirection<parser::TypeDeclarationStmt>>
97119713
&stmt) {
97129714
context().set_location(stmt.source);
9713-
const auto &[declTypeSpec, attrs, entities] = stmt.statement.value().t;
9715+
const auto &[declTypeSpec, attrs, entities]{stmt.statement.value().t};
97149716
if (const auto *intrin{
97159717
std::get_if<parser::IntrinsicTypeSpec>(&declTypeSpec.u)}) {
97169718
if (const auto *intType{std::get_if<parser::IntegerTypeSpec>(&intrin->u)}) {
97179719
if (const auto &kind{intType->v}) {
9718-
if (!parser::Unwrap<parser::KindSelector::StarSize>(*kind) &&
9720+
if (const auto *call{parser::Unwrap<parser::Call>(*kind)}) {
9721+
if (!std::get<std::list<parser::ActualArgSpec>>(call->t).empty()) {
9722+
// Accept INTEGER(int_ptr_kind()), at least. Don't allow a
9723+
// nonempty argument list, to prevent implicitly typing names
9724+
// that might appear. (TODO: But maybe INTEGER(KIND(n)) after
9725+
// an explicit declaration of 'n' would be useful.)
9726+
return;
9727+
}
9728+
} else if (!parser::Unwrap<parser::KindSelector::StarSize>(*kind) &&
97199729
!parser::Unwrap<parser::IntLiteralConstant>(*kind)) {
97209730
return;
97219731
}

flang/test/Semantics/bug122002b.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ SUBROUTINE sub00(a,b,n,m)
33
complex(2) n,m
44
! ERROR: Must have INTEGER type, but is COMPLEX(2)
55
! ERROR: Must have INTEGER type, but is COMPLEX(2)
6-
! ERROR: The type of 'b' has already been implicitly declared
6+
! ERROR: The type of 'b' has already been implicitly declared as REAL(4)
77
complex(3) a(n,m), b(size((LOG ((x * (a) - a + b / a - a))+1 - x)))
88
a = a ** n
99
! ERROR: DO controls should be INTEGER

flang/test/Semantics/bug1696.f90

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
!RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
2+
subroutine s(a,n)
3+
real a(n)
4+
!CHECK: INTEGER(KIND=8_4) n
5+
integer(int_ptr_kind()) n
6+
end

flang/test/Semantics/resolve01.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
! RUN: %python %S/test_errors.py %s %flang_fc1
22
integer :: x
3-
!ERROR: The type of 'x' has already been declared
3+
!ERROR: The type of 'x' has already been declared as INTEGER(4)
44
real :: x
55
integer(8) :: i
66
parameter(i=1,j=2,k=3)
77
integer :: j
8-
!ERROR: The type of 'k' has already been implicitly declared
8+
!ERROR: The type of 'k' has already been implicitly declared as INTEGER(4)
99
real :: k
1010
end

flang/test/Semantics/resolve05.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ subroutine s
3232
function f() result(res)
3333
integer :: res
3434
!ERROR: 'f' is already declared in this scoping unit
35-
!ERROR: The type of 'f' has already been declared
35+
!ERROR: The type of 'f' has already been declared as INTEGER(4)
3636
real :: f
3737
res = 1
3838
end

flang/test/Semantics/resolve40.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ subroutine s7
6363

6464
subroutine s8
6565
data x/1.0/
66-
!ERROR: The type of 'x' has already been implicitly declared
66+
!ERROR: The type of 'x' has already been implicitly declared as REAL(4)
6767
integer x
6868
end
6969

flang/test/Semantics/resolve52.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ subroutine s1(x)
7474
end
7575
subroutine s2(w, x)
7676
real :: x
77-
!ERROR: The type of 'x' has already been declared
77+
!ERROR: The type of 'x' has already been declared as REAL(4)
7878
class(t), allocatable :: x
7979
end
8080
subroutine s3(f)

flang/test/Semantics/resolve91.f90

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ module m
44
procedure(real), pointer :: p
55
!ERROR: EXTERNAL attribute was already specified on 'p'
66
!ERROR: POINTER attribute was already specified on 'p'
7-
!ERROR: The type of 'p' has already been declared
7+
!ERROR: The type of 'p' has already been declared as REAL(4)
88
procedure(integer), pointer :: p
99
end
1010

1111
module m1
1212
real, dimension(:), pointer :: realArray => null()
1313
!ERROR: POINTER attribute was already specified on 'realarray'
14-
!ERROR: The type of 'realarray' has already been declared
14+
!ERROR: The type of 'realarray' has already been declared as REAL(4)
1515
real, dimension(:), pointer :: realArray => localArray
1616
end module m1
1717

@@ -55,7 +55,7 @@ end module m4
5555
module m5
5656
!ERROR: Actual argument for 'string=' has bad type 'REAL(4)'
5757
character(len=len(a)) :: b
58-
!ERROR: The type of 'a' has already been implicitly declared
58+
!ERROR: The type of 'a' has already been implicitly declared as REAL(4)
5959
character(len=len(b)) :: a
6060
end module m5
6161

@@ -73,19 +73,19 @@ end module m7
7373

7474
module m8
7575
integer :: iVar = 3
76-
!ERROR: The type of 'ivar' has already been declared
76+
!ERROR: The type of 'ivar' has already been declared as INTEGER(4)
7777
integer :: iVar = 4
7878
integer, target :: jVar = 5
7979
integer, target :: kVar = 5
8080
integer, pointer :: pVar => jVar
8181
!ERROR: POINTER attribute was already specified on 'pvar'
82-
!ERROR: The type of 'pvar' has already been declared
82+
!ERROR: The type of 'pvar' has already been declared as INTEGER(4)
8383
integer, pointer :: pVar => kVar
8484
end module m8
8585

8686
module m9
8787
integer :: p, q
8888
procedure() p ! ok
89-
!ERROR: The type of 'q' has already been declared
89+
!ERROR: The type of 'q' has already been declared as INTEGER(4)
9090
procedure(real) q
9191
end module m9

0 commit comments

Comments
 (0)