aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorPeter Klausler <pklausler@nvidia.com>2022-07-18 10:27:05 -0700
committerPeter Klausler <pklausler@nvidia.com>2022-07-25 10:09:55 -0700
commit85a40ce6ddf6abf06886dc594aeb998e05f75faa (patch)
treed1620d10686a8f03e7ae24165cef4efa710d12d9 /flang
parent2c84b92346bc45a88f92d781e30daa8490049c4d (diff)
downloadllvm-85a40ce6ddf6abf06886dc594aeb998e05f75faa.zip
llvm-85a40ce6ddf6abf06886dc594aeb998e05f75faa.tar.gz
llvm-85a40ce6ddf6abf06886dc594aeb998e05f75faa.tar.bz2
[flang] Better error message for NULL() actual argument for dummy allocatable
f18 intentionally does not support the spottily-implemented language extension in which one can pass NULL() for an allocatable dummy argument. This is perhaps a sanctioned side effect in other compilers of the fact that they pass distinct "base address" and "descriptor address" physical arguments. Make the error message in this case more specific to the circumstances, and add a note to Extensions.md to clarify that this behavior is intended. (We could, with some effort in lowering, support passing NULL for an INTENT(IN) allocatable dummy, but let's see whether such nonconforming usage appears in a real application before spending any more time on it.) Differential Revision: https://reviews.llvm.org/D130380
Diffstat (limited to 'flang')
-rw-r--r--flang/docs/Extensions.md1
-rw-r--r--flang/lib/Semantics/check-call.cpp9
-rw-r--r--flang/test/Semantics/call27.f9019
3 files changed, 29 insertions, 0 deletions
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index e0c0bf6..71a3727 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -308,6 +308,7 @@ end
PGI converts the arguments while Intel and XLF replace the specific by the related generic.
* VMS listing control directives (`%LIST`, `%NOLIST`, `%EJECT`)
* Continuation lines on `INCLUDE` lines
+* `NULL()` actual argument corresponding to an `ALLOCATABLE` dummy data object
## Preprocessing behavior
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index cbf48ae..1667ac3 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -740,6 +740,15 @@ static void CheckExplicitInterfaceArg(evaluate::ActualArgument &arg,
DummyDataObject::Attr::Optional)) &&
evaluate::IsNullPointer(*expr)) {
// ok, FOO(NULL())
+ } else if (object.attrs.test(characteristics::DummyDataObject::
+ Attr::Allocatable) &&
+ evaluate::IsNullPointer(*expr)) {
+ // Unsupported extension that more or less naturally falls
+ // out of other Fortran implementations that pass separate
+ // base address and descriptor address physical arguments
+ messages.Say(
+ "Null actual argument '%s' may not be associated with allocatable %s"_err_en_US,
+ expr->AsFortran(), dummyName);
} else {
messages.Say(
"Actual argument '%s' associated with %s is not a variable or typed expression"_err_en_US,
diff --git a/flang/test/Semantics/call27.f90 b/flang/test/Semantics/call27.f90
new file mode 100644
index 0000000..97c6304
--- /dev/null
+++ b/flang/test/Semantics/call27.f90
@@ -0,0 +1,19 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+! Catch NULL() actual argement association with allocatable dummy argument
+program test
+ !ERROR: Null actual argument 'NULL()' may not be associated with allocatable dummy argument 'a='
+ call foo1(null())
+ !ERROR: Null actual argument 'NULL()' may not be associated with allocatable dummy argument 'a='
+ call foo2(null()) ! perhaps permissible later on user request
+ call foo3(null()) ! ok
+ contains
+ subroutine foo1(a)
+ real, allocatable :: a
+ end subroutine
+ subroutine foo2(a)
+ real, allocatable, intent(in) :: a
+ end subroutine
+ subroutine foo3(a)
+ real, allocatable, optional :: a
+ end subroutine
+end