Actually I also misread your question and the answers in this thread. The error that compilers return isn’t because of the pointer attribute. You get the same errors without it: Compiler Explorer
Looking into MFE (the 2023 version), it states:
Declaring a procedure to be pure is an assertion that the procedure
- if a function, does not alter any dummy argument, unless it has the
value
attribute (Section 20.8);
- does not alter any part of a variable accessed by host or use association;
- contains no local variable with a
save
attribute;
- performs no operations on an external file (Chapters 10 and 12);
- contains no stop statement
- cannot cause the exectuion of an image control statement
- does not reference an impure procedure
To ensure that these requirements are met and that a compiler can easily check that this is so, there are the following further rules:
- any dummy argument that is a procedure, and any procedure referenced, is pure;
- the intent of a dummy argument is declared unless it is a procedure, a pointer, or has the
value
attribute (Section 20.8), and this intent must be in
in the case of a function;
- any internal procedure is pure;
- the procedure do not reference an impure procedure through finalization (Section 15.11) of its function result or an intent
out
dummy argument;
- the procedure does not have an intent
out
dummy argument that is polymorphic or has a polymorphic allocatable ultimate component;
- for a function, the result is not polymorphic and allocatable, and does not have a polymorphic allocatable component; and
- …
So the issue here, is that if you had a finalizable type, that finalizer could be impure. This may not be obvious, but finalization
… also occurs (in the called procedure) when the object is passed to an intent out
dummy argument, …
just like you clarified in the original post.
Bringing us back to your question, why isn’t a polymorphic pointer intent out
dummy argument permitted, or why can’t the constraint C1587 (see @PaulT’s post) be relaxed? The target hasn’t been modified, so why would this be somehow impure?
Maybe the answer lies in what @septc says,
If you specify a pointer dummy argument, the INTENT attribute will have the following characteristics:
- INTENT(OUT) specifies that at the execution of the procedure, the association status of the pointer dummy argument is undefined
and as @jwmwalrus spelled out:
I mentioned that there could be a memory leak precisely because of that —the intent(out)
applies to the pointer, so the target is still there, but if the target is anonymous (i.e., done through allocation of that pointer), then there’ll be no way to access it anymore.
Making a pointer became undefined means changing a descriptor. The actual type would become lost on entry. It could invalidate other variables in your program. In contrast intent inout
asserts you’ll be taking control of the pointers association status and target, and and you’re fully aware how. Just one way of reasoning about this.