Skip to content

Commit 41a964c

Browse files
committed
[flang] Settle ambiguity between C795 and C721
C721 says that a type parameter value of '*' is permitted in the type-spec for a named constant; C795 says that such type parameters are allowed in type-specs only for a few kinds of things, not including named constants. The interpretation seems to depend on context, with C721 applying to intrinsic types (i.e., character) and C795 applying only to derived types. Differential Revision: https://reviews.llvm.org/D146586
1 parent 7b0c418 commit 41a964c

File tree

6 files changed

+24
-19
lines changed

6 files changed

+24
-19
lines changed

flang/lib/Semantics/check-declarations.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,7 @@ void CheckHelper::Check(const ParamValue &value, bool canBeAssumed) {
190190
if (value.isAssumed()) {
191191
if (!canBeAssumed) { // C795, C721, C726
192192
messages_.Say(
193-
"An assumed (*) type parameter may be used only for a (non-statement"
194-
" function) dummy argument, associate name, named constant, or"
195-
" external function result"_err_en_US);
193+
"An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, character named constant, or external function result"_err_en_US);
196194
}
197195
} else {
198196
CheckSpecExpr(value.GetExplicit());
@@ -323,8 +321,9 @@ void CheckHelper::Check(const Symbol &symbol) {
323321
"A dummy procedure of a pure subprogram must be pure"_err_en_US);
324322
}
325323
}
326-
if (type) { // Section 7.2, paragraph 7
327-
bool canHaveAssumedParameter{IsNamedConstant(symbol) ||
324+
if (type) { // Section 7.2, paragraph 7; C795
325+
bool isChar{type->category() == DeclTypeSpec::Character};
326+
bool canHaveAssumedParameter{(isChar && IsNamedConstant(symbol)) ||
328327
(IsAssumedLengthCharacter(symbol) && // C722
329328
(IsExternal(symbol) ||
330329
ClassifyProcedure(symbol) ==
@@ -333,8 +332,7 @@ void CheckHelper::Check(const Symbol &symbol) {
333332
if (!IsStmtFunctionDummy(symbol)) { // C726
334333
if (const auto *object{symbol.detailsIf<ObjectEntityDetails>()}) {
335334
canHaveAssumedParameter |= object->isDummy() ||
336-
(object->isFuncResult() &&
337-
type->category() == DeclTypeSpec::Character) ||
335+
(isChar && object->isFuncResult()) ||
338336
IsStmtFunctionResult(symbol); // Avoids multiple messages
339337
} else {
340338
canHaveAssumedParameter |= symbol.has<AssocEntityDetails>();

flang/test/Semantics/call05.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ module m
2020
class(t2), allocatable :: pa2(:)
2121
class(*), pointer :: up(:)
2222
class(*), allocatable :: ua(:)
23-
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, named constant, or external function result
23+
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, character named constant, or external function result
2424
type(pdt(*)), pointer :: amp(:)
25-
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, named constant, or external function result
25+
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, character named constant, or external function result
2626
type(pdt(*)), allocatable :: ama(:)
2727
type(pdt(:)), pointer :: dmp(:)
2828
type(pdt(:)), allocatable :: dma(:)

flang/test/Semantics/call31.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module m
66
subroutine subr(parg)
77
!PORTABILITY: A dummy procedure pointer should not have assumed-length CHARACTER(*) result type
88
procedure(character(*)), pointer :: parg
9-
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, named constant, or external function result
9+
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, character named constant, or external function result
1010
procedure(character(*)), pointer :: plocal
1111
print *, parg()
1212
plocal => parg

flang/test/Semantics/resolve73.f90

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@
22
! C721 A type-param-value of * shall be used only
33
! * to declare a dummy argument,
44
! * to declare a named constant,
5-
! * in the type-spec of an ALLOCATE statement wherein each allocate-object is
5+
! * in the type-spec of an ALLOCATE statement wherein each allocate-object is
66
! a dummy argument of type CHARACTER with an assumed character length,
7-
! * in the type-spec or derived-type-spec of a type guard statement (11.1.11),
7+
! * in the type-spec or derived-type-spec of a type guard statement (11.1.11),
88
! or
99
! * in an external function, to declare the character length parameter of the function result.
10+
! Note also C795 for derived types (C721 applies to intrinsic types)
1011
subroutine s(arg)
1112
character(len=*), pointer :: arg
1213
character*(*), parameter :: cvar1 = "abc"
1314
character*4, cvar2
1415
character(len=4_4) :: cvar3
15-
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, named constant, or external function result
16+
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, character named constant, or external function result
1617
character(len=*) :: cvar4
1718

1819
type derived(param)
@@ -26,6 +27,12 @@ function fun()
2627
end function fun
2728
end interface
2829

30+
type t(len)
31+
integer, len :: len
32+
end type
33+
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, character named constant, or external function result
34+
type(t(*)), parameter :: p2 = t(123)() ! C795
35+
2936
select type (ax => a%x)
3037
type is (integer)
3138
print *, "hello"

flang/test/Semantics/resolve74.f90

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ subroutine s()
1010
type(derived(34)) :: a
1111

1212
procedure(character(len=*)) :: externCharFunc
13-
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, named constant, or external function result
13+
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, character named constant, or external function result
1414
procedure(type(derived(param =*))) :: externDerivedFunc
1515

1616
interface
@@ -24,14 +24,14 @@ function works()
2424
type(derived(param=4)) :: works
2525
end function works
2626

27-
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, named constant, or external function result
27+
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, character named constant, or external function result
2828
function fails1()
2929
character(len=*) :: fails1
3030
end function fails1
3131

32-
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, named constant, or external function result
32+
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, character named constant, or external function result
3333
function fails2()
34-
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, named constant, or external function result
34+
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, character named constant, or external function result
3535
type(derived(param=*)) :: fails2
3636
end function fails2
3737

flang/test/Semantics/resolve75.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ subroutine s()
77
implicit character(len=*) (d)
88
stmtFunc1 (x) = x * 32
99
cStmtFunc2 (x) = "abc"
10-
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, named constant, or external function result
10+
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, character named constant, or external function result
1111
cStmtFunc3 (dummy) = "abc"
12-
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, named constant, or external function result
12+
!ERROR: An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, character named constant, or external function result
1313
dStmtFunc3 (x) = "abc"
1414
end subroutine s

0 commit comments

Comments
 (0)