[flang] Warn about assumed-rank items in I/O lists (#182957)
An assumed-rank dummy argument is not a conforming I/O list or NAMELIST group item. Add a -pedantic warning and some documentation.
This commit is contained in:
parent
1c2e9b1ea6
commit
cbcaae2b5c
@ -483,6 +483,7 @@ end
|
||||
are to the same value. Distinct initializations remain errors.
|
||||
* A pointer component that has no default initialization or explicit value
|
||||
in a structure constructor is defaulted to `NULL()`.
|
||||
* An assumed-rank entity is an acceptable `NAMELIST` group item.
|
||||
|
||||
### Extensions supported when enabled by options
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
|
||||
ForwardRefExplicitTypeDummy, InaccessibleDeferredOverride,
|
||||
CudaWarpMatchFunction, DoConcurrentOffload, TransferBOZ, Coarray,
|
||||
PointerPassObject, MultipleIdenticalDATA,
|
||||
DefaultStructConstructorNullPointer)
|
||||
DefaultStructConstructorNullPointer, AssumedRankIoItem)
|
||||
|
||||
// Portability and suspicious usage warnings
|
||||
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
|
||||
|
||||
@ -327,10 +327,12 @@ void IoChecker::Enter(const parser::InputItem &spec) {
|
||||
}
|
||||
CheckForDefinableVariable(*var, "Input");
|
||||
if (auto expr{AnalyzeExpr(context_, *var)}) {
|
||||
auto at{var->GetSource()};
|
||||
CheckForAssumedRank(UnwrapWholeSymbolDataRef(*expr), at);
|
||||
CheckForBadIoType(*expr,
|
||||
flags_.test(Flag::FmtOrNml) ? common::DefinedIo::ReadFormatted
|
||||
: common::DefinedIo::ReadUnformatted,
|
||||
var->GetSource());
|
||||
at);
|
||||
}
|
||||
}
|
||||
|
||||
@ -651,11 +653,14 @@ void IoChecker::Enter(const parser::OutputItem &item) {
|
||||
} else if (IsProcedure(*expr)) {
|
||||
context_.Say(parser::FindSourceLocation(*x),
|
||||
"Output item must not be a procedure"_err_en_US); // C1233
|
||||
} else {
|
||||
auto at{parser::FindSourceLocation(item)};
|
||||
CheckForAssumedRank(UnwrapWholeSymbolDataRef(*expr), at);
|
||||
CheckForBadIoType(*expr,
|
||||
flags_.test(Flag::FmtOrNml) ? common::DefinedIo::WriteFormatted
|
||||
: common::DefinedIo::WriteUnformatted,
|
||||
at);
|
||||
}
|
||||
CheckForBadIoType(*expr,
|
||||
flags_.test(Flag::FmtOrNml) ? common::DefinedIo::WriteFormatted
|
||||
: common::DefinedIo::WriteUnformatted,
|
||||
parser::FindSourceLocation(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1228,6 +1233,17 @@ parser::Message *IoChecker::CheckForBadIoType(const Symbol &symbol,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void IoChecker::CheckForAssumedRank(
|
||||
const Symbol *symbol, parser::CharBlock namelistLocation) const {
|
||||
if (symbol && IsAssumedRank(*symbol)) {
|
||||
evaluate::AttachDeclaration(
|
||||
context_.Say(namelistLocation,
|
||||
"Assumed-rank object '%s' may not be an I/O list item"_err_en_US,
|
||||
symbol->name()),
|
||||
*symbol);
|
||||
}
|
||||
}
|
||||
|
||||
void IoChecker::CheckNamelist(const Symbol &namelist, common::DefinedIo which,
|
||||
parser::CharBlock namelistLocation) const {
|
||||
if (!context_.HasError(namelist)) {
|
||||
|
||||
@ -133,6 +133,7 @@ private:
|
||||
const SomeExpr &, common::DefinedIo, parser::CharBlock) const;
|
||||
parser::Message *CheckForBadIoType(
|
||||
const Symbol &, common::DefinedIo, parser::CharBlock) const;
|
||||
void CheckForAssumedRank(const Symbol *, parser::CharBlock) const;
|
||||
|
||||
void CheckNamelist(
|
||||
const Symbol &, common::DefinedIo, parser::CharBlock) const;
|
||||
|
||||
@ -7228,6 +7228,13 @@ void DeclarationVisitor::FinishNamelists() {
|
||||
} else if (!ConvertToObjectEntity(symbol->GetUltimate())) {
|
||||
SayWithDecl(name, *symbol, "'%s' is not a variable"_err_en_US);
|
||||
context().SetError(*groupSymbol);
|
||||
} else if (IsAssumedRank(*symbol)) {
|
||||
evaluate::AttachDeclaration(
|
||||
context().Warn(common::LanguageFeature::AssumedRankIoItem,
|
||||
name.source,
|
||||
"Assumed-rank object '%s' should not be a namelist group item"_port_en_US,
|
||||
symbol->name()),
|
||||
*symbol);
|
||||
}
|
||||
symbol->GetUltimate().set(Symbol::Flag::InNamelist);
|
||||
details->add_object(*symbol);
|
||||
|
||||
15
flang/test/Semantics/io16.f90
Normal file
15
flang/test/Semantics/io16.f90
Normal file
@ -0,0 +1,15 @@
|
||||
! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
|
||||
subroutine assumedRank(x, y)
|
||||
real x(..), y(*)
|
||||
!PORTABILITY: Assumed-rank object 'x' should not be a namelist group item [-Wassumed-rank-io-item]
|
||||
!ERROR: A namelist group object 'y' must not be assumed-size
|
||||
namelist /nml/x, y
|
||||
!ERROR: Assumed-rank object 'x' may not be an I/O list item
|
||||
!ERROR: Whole assumed-size array 'y' may not appear here without subscripts
|
||||
read *, x, y
|
||||
!ERROR: Assumed-rank object 'x' may not be an I/O list item
|
||||
!ERROR: Whole assumed-size array 'y' may not appear here without subscripts
|
||||
print *, x, y
|
||||
read(*,nml=nml)
|
||||
write(*,nml=nml)
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user