[flang-commits] [flang] 3bca850 - [flang] Correct checking of PRESENT() (#78364)
via flang-commits
flang-commits at lists.llvm.org
Thu Jan 25 14:20:21 PST 2024
Author: Peter Klausler
Date: 2024-01-25T14:20:16-08:00
New Revision: 3bca8506ab65c66e32695ba50571c4384be8e4d1
URL: https://github.com/llvm/llvm-project/commit/3bca8506ab65c66e32695ba50571c4384be8e4d1
DIFF: https://github.com/llvm/llvm-project/commit/3bca8506ab65c66e32695ba50571c4384be8e4d1.diff
LOG: [flang] Correct checking of PRESENT() (#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.
Added:
flang/test/Semantics/present01.f90
Modified:
flang/lib/Evaluate/intrinsics.cpp
flang/lib/Semantics/check-call.cpp
Removed:
################################################################################
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 7d2e45dcbe96ded..e3a9d54136ae9a2 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -2896,8 +2896,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(
@@ -2939,20 +2937,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 c924a817ec7e19e..80ec1310a31432a 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -1470,6 +1470,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) {
@@ -1680,6 +1704,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 000000000000000..5b0233931ac97d2
--- /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