// technically legal but worth emitting a warning
// llvm-project issue #58973: constant actual argument passed in where dummy
// argument is marked volatile
- if (dummyIsVolatile && !IsVariable(actual)) {
+ bool actualIsVariable{evaluate::IsVariable(actual)};
+ if (dummyIsVolatile && !actualIsVariable) {
messages.Say(
"actual argument associated with VOLATILE %s is not a variable"_warn_en_US,
dummyName);
"Actual argument associated with %s may not be null pointer %s"_err_en_US,
dummyName, actual.AsFortran());
}
+
+ // Warn about dubious actual argument association with a TARGET dummy argument
+ if (dummy.attrs.test(characteristics::DummyDataObject::Attr::Target)) {
+ bool actualIsTemp{!actualIsVariable || HasVectorSubscript(actual) ||
+ evaluate::ExtractCoarrayRef(actual)};
+ if (actualIsTemp) {
+ messages.Say(
+ "Any pointer associated with TARGET %s during this call will not be associated with the value of '%s' afterwards"_warn_en_US,
+ dummyName, actual.AsFortran());
+ } else {
+ auto actualSymbolVector{GetSymbolVector(actual)};
+ if (!evaluate::GetLastTarget(actualSymbolVector)) {
+ messages.Say(
+ "Any pointer associated with TARGET %s during this call must not be used afterwards, as '%s' is not a target"_warn_en_US,
+ dummyName, actual.AsFortran());
+ }
+ }
+ }
}
static void CheckProcedureArg(evaluate::ActualArgument &arg,
--- /dev/null
+! RUN: %python %S/test_errors.py %s %flang_fc1 -Werror
+module m
+ contains
+ subroutine foo(a)
+ real, intent(in), target :: a(:)
+ end subroutine
+end module
+
+program test
+ use m
+ real, target :: a(1)
+ real :: b(1)
+ call foo(a) ! ok
+ !WARNING: Any pointer associated with TARGET dummy argument 'a=' during this call must not be used afterwards, as 'b' is not a target
+ call foo(b)
+ !WARNING: Any pointer associated with TARGET dummy argument 'a=' during this call will not be associated with the value of '(a)' afterwards
+ call foo((a))
+ !WARNING: Any pointer associated with TARGET dummy argument 'a=' during this call will not be associated with the value of 'a([INTEGER(8)::1_8])' afterwards
+ call foo(a([1]))
+ !ERROR: Scalar actual argument may not be associated with assumed-shape dummy argument 'a='
+ call foo(a(1))
+end