[flang-commits] [flang] [flang] Refine handling of NULL() actual to non-optional allocatable … (PR #116126)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Mon Feb 24 12:29:42 PST 2025
https://github.com/klausler updated https://github.com/llvm/llvm-project/pull/116126
>From cfeca1e92b9ca0c7409a742265101076ef241c4b Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Wed, 13 Nov 2024 16:13:37 -0800
Subject: [PATCH] [flang] Refine handling of NULL() actual to non-optional
allocatable dummy
We presently allow a NULL() actual argument to associate with a non-optional
dummy allocatable argument only under INTENT(IN). This is too strict, as
it precludes the case of a dummy argument with default intent.
Continue to require that the actual argument be definable under INTENT(OUT)
and INTENT(IN OUT), and (contra XLF) interpret NULL() as being an expression,
not a definable variable, even when it is given an allocatable MOLD.
Fixes https://github.com/llvm/llvm-project/issues/115984.
---
.../include/flang/Support/Fortran-features.h | 3 +-
flang/lib/Semantics/check-call.cpp | 51 ++++++++++---------
flang/lib/Support/Fortran-features.cpp | 2 +
flang/test/Semantics/call27.f90 | 16 +++++-
4 files changed, 47 insertions(+), 25 deletions(-)
diff --git a/flang/include/flang/Support/Fortran-features.h b/flang/include/flang/Support/Fortran-features.h
index 44ba6428e6c93..356623c643e46 100644
--- a/flang/include/flang/Support/Fortran-features.h
+++ b/flang/include/flang/Support/Fortran-features.h
@@ -74,7 +74,8 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
IndexVarRedefinition, IncompatibleImplicitInterfaces,
VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg,
MismatchingDummyProcedure, SubscriptedEmptyArray, UnsignedLiteralTruncation,
- CompatibleDeclarationsFromDistinctModules)
+ CompatibleDeclarationsFromDistinctModules,
+ NullActualForDefaultIntentAllocatable)
using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index e396ece303103..93ae05e2902f0 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -793,21 +793,21 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
}
} else if (actualIsNull) {
if (dummyIsOptional) {
- } else if (dummy.intent == common::Intent::In) {
- // Extension (Intel, NAG, XLF): a NULL() pointer is an acceptable
- // actual argument for an INTENT(IN) allocatable dummy, and it
- // is treated as an unassociated allocatable.
- if (context.ShouldWarn(
- common::LanguageFeature::NullActualForAllocatable)) {
- messages.Say(common::LanguageFeature::NullActualForAllocatable,
- "Allocatable %s is associated with a null pointer"_port_en_US,
- dummyName);
- }
- } else {
+ } else if (dummy.intent == common::Intent::Default &&
+ context.ShouldWarn(
+ common::UsageWarning::NullActualForDefaultIntentAllocatable)) {
messages.Say(
- "A null pointer may not be associated with allocatable %s without INTENT(IN)"_err_en_US,
+ "A null pointer should not be associated with allocatable %s without INTENT(IN)"_warn_en_US,
+ dummyName);
+ } else if (dummy.intent == common::Intent::In &&
+ context.ShouldWarn(
+ common::LanguageFeature::NullActualForAllocatable)) {
+ messages.Say(common::LanguageFeature::NullActualForAllocatable,
+ "Allocatable %s is associated with a null pointer"_port_en_US,
dummyName);
}
+ // INTENT(OUT) and INTENT(IN OUT) cases are caught elsewhere as being
+ // undefinable actual arguments.
} else {
messages.Say(
"ALLOCATABLE %s must be associated with an ALLOCATABLE actual argument"_err_en_US,
@@ -1292,19 +1292,24 @@ static void CheckExplicitInterfaceArg(evaluate::ActualArgument &arg,
} else if (object.attrs.test(characteristics::DummyDataObject::
Attr::Allocatable) &&
evaluate::IsNullPointer(*expr)) {
- if (object.intent == common::Intent::In) {
- // Extension (Intel, NAG, XLF); see CheckExplicitDataArg.
- if (context.ShouldWarn(common::LanguageFeature::
- NullActualForAllocatable)) {
- messages.Say(
- common::LanguageFeature::NullActualForAllocatable,
- "Allocatable %s is associated with NULL()"_port_en_US,
- dummyName);
- }
- } else {
+ if (object.intent == common::Intent::Out ||
+ object.intent == common::Intent::InOut) {
messages.Say(
- "NULL() actual argument '%s' may not be associated with allocatable %s without INTENT(IN)"_err_en_US,
+ "NULL() actual argument '%s' may not be associated with allocatable dummy argument %s that is INTENT(OUT) or INTENT(IN OUT)"_err_en_US,
expr->AsFortran(), dummyName);
+ } else if (object.intent == common::Intent::Default &&
+ context.ShouldWarn(common::UsageWarning::
+ NullActualForDefaultIntentAllocatable)) {
+ messages.Say(common::UsageWarning::
+ NullActualForDefaultIntentAllocatable,
+ "NULL() actual argument '%s' should not be associated with allocatable dummy argument %s without INTENT(IN)"_warn_en_US,
+ expr->AsFortran(), dummyName);
+ } else if (context.ShouldWarn(common::LanguageFeature::
+ NullActualForAllocatable)) {
+ messages.Say(
+ common::LanguageFeature::NullActualForAllocatable,
+ "Allocatable %s is associated with %s"_port_en_US,
+ dummyName, expr->AsFortran());
}
} else {
messages.Say(
diff --git a/flang/lib/Support/Fortran-features.cpp b/flang/lib/Support/Fortran-features.cpp
index bbeb4b15a0486..4bc92f3924ef6 100644
--- a/flang/lib/Support/Fortran-features.cpp
+++ b/flang/lib/Support/Fortran-features.cpp
@@ -84,8 +84,10 @@ LanguageFeatureControl::LanguageFeatureControl() {
warnUsage_.set(UsageWarning::UndefinedFunctionResult);
warnUsage_.set(UsageWarning::UselessIomsg);
warnUsage_.set(UsageWarning::UnsignedLiteralTruncation);
+ warnUsage_.set(UsageWarning::NullActualForDefaultIntentAllocatable);
// New warnings, on by default
warnLanguage_.set(LanguageFeature::SavedLocalInSpecExpr);
+ warnLanguage_.set(LanguageFeature::NullActualForAllocatable);
}
// Ignore case and any inserted punctuation (like '-'/'_')
diff --git a/flang/test/Semantics/call27.f90 b/flang/test/Semantics/call27.f90
index 062df6e45da89..135d6c06dcb4a 100644
--- a/flang/test/Semantics/call27.f90
+++ b/flang/test/Semantics/call27.f90
@@ -1,12 +1,26 @@
! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
! Catch NULL() actual argument association with allocatable dummy argument
program test
- !ERROR: NULL() actual argument 'NULL()' may not be associated with allocatable dummy argument 'a=' without INTENT(IN)
+ real, allocatable :: a
+ !ERROR: NULL() actual argument 'NULL()' may not be associated with allocatable dummy argument dummy argument 'a=' that is INTENT(OUT) or INTENT(IN OUT)
+ call foo0(null())
+ !WARNING: NULL() actual argument 'NULL()' should not be associated with allocatable dummy argument dummy argument 'a=' without INTENT(IN)
call foo1(null())
!PORTABILITY: Allocatable dummy argument 'a=' is associated with NULL()
call foo2(null())
call foo3(null()) ! ok
+ !ERROR: Actual argument associated with INTENT(IN OUT) dummy argument 'a=' is not definable
+ !BECAUSE: 'null(mold=a)' is a null pointer
+ call foo0(null(mold=a))
+ !WARNING: A null pointer should not be associated with allocatable dummy argument 'a=' without INTENT(IN)
+ call foo1(null(mold=a))
+ !PORTABILITY: Allocatable dummy argument 'a=' is associated with a null pointer
+ call foo2(null(mold=a))
+ call foo3(null(mold=a)) ! ok
contains
+ subroutine foo0(a)
+ real, allocatable, intent(in out) :: a
+ end subroutine
subroutine foo1(a)
real, allocatable :: a
end subroutine
More information about the flang-commits
mailing list