[flang-commits] [flang] [flang] Correct checking of PRESENT() (PR #78364)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Tue Jan 16 15:45:15 PST 2024
https://github.com/klausler created https://github.com/llvm/llvm-project/pull/78364
The argument to the PRESENT() intrinsic function must be the name of a a whole OPTIONAL dummy argument.
Fixes llvm-test-suite/Fortran/gfortran/regression/present_1.f90.
>From 6423bbbb5a21f4f3ee96ab7814eaf4acb121ee6a Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Tue, 16 Jan 2024 15:39:56 -0800
Subject: [PATCH] [flang] Correct checking of PRESENT()
The argument to the PRESENT() intrinsic function must be the name
of a a whole OPTIONAL dummy argument.
Fixes llvm-test-suite/Fortran/gfortran/regression/present_1.f90.
---
flang/lib/Evaluate/intrinsics.cpp | 16 ----------------
flang/lib/Semantics/check-call.cpp | 26 ++++++++++++++++++++++++++
flang/test/Semantics/present01.f90 | 21 +++++++++++++++++++++
3 files changed, 47 insertions(+), 16 deletions(-)
create mode 100644 flang/test/Semantics/present01.f90
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index da6d5970089884..e1435d3678a46d 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -2881,8 +2881,6 @@ static bool ApplySpecificChecks(SpecificCall &call, FoldingContext &context) {
arg ? arg->sourceLocation() : context.messages().at(),
"Argument of ALLOCATED() must be an ALLOCATABLE object or component"_err_en_US);
}
- } else if (name == "associated" || name == "reduce") {
- // Now handled in Semantics/check-call.cpp
} else if (name == "atomic_and" || name == "atomic_or" ||
name == "atomic_xor") {
return CheckForCoindexedObject(
@@ -2924,20 +2922,6 @@ static bool ApplySpecificChecks(SpecificCall &call, FoldingContext &context) {
arg ? arg->sourceLocation() : context.messages().at(),
"Argument of LOC() must be an object or procedure"_err_en_US);
}
- } else if (name == "present") {
- const auto &arg{call.arguments[0]};
- if (arg) {
- if (const auto *expr{arg->UnwrapExpr()}) {
- if (const Symbol *symbol{UnwrapWholeSymbolDataRef(*expr)}) {
- ok = symbol->attrs().test(semantics::Attr::OPTIONAL);
- }
- }
- }
- if (!ok) {
- context.messages().Say(
- arg ? arg->sourceLocation() : context.messages().at(),
- "Argument of PRESENT() must be the name of an OPTIONAL dummy argument"_err_en_US);
- }
} else if (name == "ucobound") {
return CheckDimAgainstCorank(call, context);
}
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index a8927e94481d4b..d770c94b603f19 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -1468,6 +1468,30 @@ static void CheckMove_Alloc(evaluate::ActualArguments &arguments,
}
}
+// PRESENT (F'2023 16.9.163)
+static void CheckPresent(evaluate::ActualArguments &arguments,
+ parser::ContextualMessages &messages) {
+ if (arguments.size() == 1) {
+ if (const auto &arg{arguments[0]}; arg) {
+ const Symbol *symbol{nullptr};
+ if (const auto *expr{arg->UnwrapExpr()}) {
+ if (const auto *proc{
+ std::get_if<evaluate::ProcedureDesignator>(&expr->u)}) {
+ symbol = proc->GetSymbol();
+ } else {
+ symbol = evaluate::UnwrapWholeSymbolDataRef(*expr);
+ }
+ } else {
+ symbol = arg->GetAssumedTypeDummy();
+ }
+ if (!symbol || !symbol->attrs().test(semantics::Attr::OPTIONAL)) {
+ messages.Say(arg ? arg->sourceLocation() : messages.at(),
+ "Argument of PRESENT() must be the name of a whole OPTIONAL dummy argument"_err_en_US);
+ }
+ }
+ }
+}
+
// REDUCE (F'2023 16.9.173)
static void CheckReduce(
evaluate::ActualArguments &arguments, evaluate::FoldingContext &context) {
@@ -1678,6 +1702,8 @@ static void CheckSpecificIntrinsic(evaluate::ActualArguments &arguments,
CheckAssociated(arguments, context, scope);
} else if (intrinsic.name == "move_alloc") {
CheckMove_Alloc(arguments, context.foldingContext().messages());
+ } else if (intrinsic.name == "present") {
+ CheckPresent(arguments, context.foldingContext().messages());
} else if (intrinsic.name == "reduce") {
CheckReduce(arguments, context.foldingContext());
} else if (intrinsic.name == "transfer") {
diff --git a/flang/test/Semantics/present01.f90 b/flang/test/Semantics/present01.f90
new file mode 100644
index 00000000000000..5b0233931ac97d
--- /dev/null
+++ b/flang/test/Semantics/present01.f90
@@ -0,0 +1,21 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+module m
+ type dt
+ real a
+ end type
+ contains
+ subroutine s(a,b,p,unl)
+ type(dt), optional :: a(:), b
+ procedure(sin), optional :: p
+ type(*), optional :: unl
+ print *, present(a) ! ok
+ print *, present(p) ! ok
+ print *, present(unl) ! ok
+ !ERROR: Argument of PRESENT() must be the name of a whole OPTIONAL dummy argument
+ print *, present(a(1))
+ !ERROR: Argument of PRESENT() must be the name of a whole OPTIONAL dummy argument
+ print *, present(b%a)
+ !ERROR: Argument of PRESENT() must be the name of a whole OPTIONAL dummy argument
+ print *, present(a(1)%a)
+ end
+end
More information about the flang-commits
mailing list