Bug 45740 - PROCEDURE POINTER and PROTECTED: Accepts/ICEs on invalid code
PROCEDURE POINTER and PROTECTED: Accepts/ICEs on invalid code
Status: RESOLVED INVALID
Product: gcc
Classification: Unclassified
Component: fortran
4.6.0
: P3 normal
: ---
Assigned To: janus
: accepts-invalid
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2010-09-21 12:31 UTC by Tobias Burnus
Modified: 2010-10-03 20:25 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-10-02 13:25:23


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2010-09-21 12:31:56 UTC
From Fortran 2008:

C549 An entity with the PROTECTED attribute shall be a procedure pointer or variable.

C551 A nonpointer object that has the PROTECTED attribute and is accessed by use association shall not appear in a variable definition context (16.6.7) or as the data-target or proc-target in a pointer-assignment-stmt.

C552 A pointer that has the PROTECTED attribute and is accessed by use association shall not appear in a pointer association context (16.6.8).


module m
  procedure(), pointer :: p, p2
  protected :: p
end module m

subroutine one
  use m
  procedure(), pointer :: ptr1 => p  ! Invalid
end subroutine one

subroutine two
  use m
  procedure(), pointer :: ptr2
  ptr2 => p  ! Invalid
end subroutine two

subroutine three
  use m
  procedure(), pointer :: ptr3 => p2  ! Valid
  call ptr3()  ! ICE, related to PR 45290
! internal compiler error: in record_reference, at cgraphbuild.c:60
end subroutine three
Comment 1 Tobias Burnus 2010-09-21 13:47:22 UTC
TODO: Check whether the code is really invalid - C551 talks only about nonpointers, but it also talks about "proc-target" - which only applies to procedures and the PROTECTED only applies per C549 to variables and procedure pointers.


Re-reading F2008's "4.5.4.6 Default initialization for components" and R505 and following, the
    procedure(), pointer :: ptr3 => p2  ! Valid
is invalid as "p2" does not have the target attribute.
Comment 2 Tobias Burnus 2010-09-21 14:19:49 UTC
(In reply to comment #1)
> TODO: Check whether the code is really invalid

I have now asked at J3,
cf. http://j3-fortran.org/pipermail/j3/2010-September/thread.html
Comment 3 Tobias Burnus 2010-10-02 11:33:43 UTC
Summary as far I understand it. Cf. http://j3-fortran.org/pipermail/j3/2010-September/003852.html :

module m
  procedure(), pointer :: p, p2
  protected :: p
end module m

subroutine two
  use m
  procedure(), pointer :: ptr2
  ptr2 => p  ! Invalid
end subroutine two

It is invalid as "p" is PROTECTED, but gfortran does not diagnose this. That's something the variable-definition patch misses.

 * * *

subroutine one
  use m
  procedure(), pointer :: ptr1 => p2
end subroutine one

That's invalid as "p2" is a pointer, cf. PR 45290.
Comment 4 janus 2010-10-02 13:25:23 UTC
Note: The problem not only applies to procedure pointers, but also to data pointers, as the following example shows:


module m
  integer, pointer :: p
  protected :: p
end module m

  use m
  integer, pointer :: ptr2
  ptr2 => p  ! Invalid per F08:C551 (undiagnosed)
end
Comment 5 janus 2010-10-02 14:19:18 UTC
(In reply to comment #4)
> Note: The problem not only applies to procedure pointers, but also to data
> pointers, as the following example shows:

Well, at least this example is invalid by the same logic as the original test case. However, I'm not sure I fully understand this logic ...

In contrast to my annotation in the previous example, C551 does not apply (since it only talks about nonpointers). And C552 only says that a protected pointer cannot appear in a "pointer association context" (i.e. the LHS of a pointer assignment). It does not say that a protected pointer cannot appear on the RHS of a pointer assignment!?!
Comment 6 Tobias Burnus 2010-10-02 14:39:30 UTC
(In reply to comment #5)
> In contrast to my annotation in the previous example, C551 does not apply
> (since it only talks about nonpointers). And C552 only says that a protected
> pointer cannot appear in a "pointer association context" (i.e. the LHS of a
> pointer assignment). It does not say that a protected pointer cannot appear on
> the RHS of a pointer assignment!?!

I think I scratch that part. I still do not see what is meant by the "proc-pointer" part in

"C551 A nonpointer object that has the PROTECTED attribute and is accessed by use association shall not appear [...] as the [...] proc-target in a pointer-assignment-stmt."

as PROTECTED can only be applied to proc pointers (and normal variables).


I think I will close this PR as INVALID - as the other issue is taken care of in 
PR 45290.
Comment 7 janus 2010-10-02 15:25:04 UTC
(In reply to comment #6)
> I still do not see what is meant by the
> "proc-pointer" part in
> 
> "C551 A nonpointer object that has the PROTECTED attribute and is accessed by
> use association shall not appear [...] as the [...] proc-target in a
> pointer-assignment-stmt."
> 
> as PROTECTED can only be applied to proc pointers (and normal variables).

Ok, I think the only way this half-sentence and the interpretation on the J3 mailing list make sense, is via the following interpretation. Consider:

integer, pointer :: lhs, rhs
lhs => rhs

In such a pointer assignment statement, the object on the right hand side supposedly does not have the pointer attribute (the pointer is dereferenced, so that 'lhs' will point to the target of 'rhs'). With this reading, C551 can be applied to (proc-/data-)pointer assignments as well, and the sentence about 'proc-target' does make sense.

[I hate these kinds of subtleties in reading the standard and hope I got it right this time.]

Also, from a "common sense" POV, it is important to reject protected pointers on the rhs of a pointer assignment, otherwise the PROTECTED feature could be circumvented this way.
Comment 8 janus 2010-10-02 18:51:21 UTC
Patch:


Index: gcc/fortran/expr.c
===================================================================
--- gcc/fortran/expr.c	(revision 164900)
+++ gcc/fortran/expr.c	(working copy)
@@ -3250,6 +3250,14 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_ex
       return FAILURE;
     }
 
+  /* Check for F08:C551.  */
+  if (rvalue->expr_type == EXPR_VARIABLE
+      && rvalue->symtree->n.sym->attr.is_protected
+      && rvalue->symtree->n.sym->attr.use_assoc)
+    gfc_error ("Variable '%s' is PROTECTED and can not appear in a "
+	       "pointer assignment statement at %L",
+	       rvalue->symtree->n.sym->name, &rvalue->where);
+
   proc_pointer = lvalue->symtree->n.sym->attr.proc_pointer;
 
   rank_remap = false;
Comment 9 Tobias Burnus 2010-10-02 19:52:17 UTC
(In reply to comment #7)
> Ok, I think the only way this half-sentence and the interpretation on the J3
> mailing list make sense, is via the following interpretation.

I disagree and start to come to the conclusion that one should asked at the J3 mailing list - I just have no idea how to ask sensible for the proc-target part of C551.

> Consider:
> integer, pointer :: lhs, rhs
> lhs => rhs
> 
> In such a pointer assignment statement, the object on the right hand side
> supposedly does not have the pointer attribute

Why? I see on the right hand side a "data-target" looks perfectly like a pointer and matches also the definition
"Entities with the POINTER attribute can be associated with different data objects or procedures during execution of a program."

I could do:
  rhs => targer
while (even if rhs were an array) I could not do
  rhs(4) => target

> that 'lhs' will point to the target of 'rhs'). With this reading, C551 can be
> applied to (proc-/data-)pointer assignments as well, and the sentence about
> 'proc-target' does make sense.

Well, it makes sense here - but you open at the same time the box of the Pandora.

> Also, from a "common sense" POV, it is important to reject protected pointers
> on the rhs of a pointer assignment, otherwise the PROTECTED feature could be
> circumvented this way.

Actually: How? I see how you can modify the pointer target - but not the pointer itself.


Thus:
- I think C551's "or proc-target" does not make sense as it is unreachable
- With regards to C551/C552 gfortan handles it seemingly correctly
- I need a stronger coffee when reading the fine prints of the Fortran standard

With your definition, you allow for:
  pointer :: ptr2 => ptr1
which is difficult to get correct and I believe is invalid as "ptr1" has the POINTER and not the TARGET attribute. A POINTER is allowed for a normal, non-initialization expression.
Comment 10 janus 2010-10-03 20:25:36 UTC
(In reply to comment #9)
> Thus:
> - I think C551's "or proc-target" does not make sense as it is unreachable
> - With regards to C551/C552 gfortan handles it seemingly correctly
> - I need a stronger coffee when reading the fine prints of the Fortran standard

Ok, I agree. I think I had misread Van Snyder's interpretation on the J3 mailing list (and possibly parts of the standard). Sorry about the confusion. Closing as invalid.