Bug 54594 - [OOP] Type-bound ASSIGNMENTs (elemental + array version) rejected as ambiguous
Summary: [OOP] Type-bound ASSIGNMENTs (elemental + array version) rejected as ambiguous
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: janus
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2012-09-15 18:12 UTC by Tobias Burnus
Modified: 2012-09-16 22:06 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-09-15 00:00:00


Attachments
generic_defined_assignment.f90 (401 bytes, text/plain)
2012-09-15 18:12 UTC, Tobias Burnus
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2012-09-15 18:12:51 UTC
Created attachment 28197 [details]
generic_defined_assignment.f90

(Note, I haven't checked whether the following bug report is valid.=

The following program by James Van Buskirk compiles with Cray ftn and prints:

 Explicit calls:
 Overloaded
 Overloaded
 Overloaded
 Implicit calls:
 Overloaded array->array
 Overloaded scalar->array
 Overloaded

However, it fails with gfortran with the error:

     generic :: assignment(=) => a_ass
                                1
Error: 'a_ass' and 'a_ass_sv' for GENERIC '=' at (1) are ambiguous


Note for the defined assignment, you need the patch for PR46897, cf. http://gcc.gnu.org/ml/fortran/2012-09/msg00034.html

See also discussion at https://groups.google.com/forum/?fromgroups=#!topic/comp.lang.fortran/5eAz5ns6AG0
Comment 1 janus 2012-09-15 18:39:40 UTC
Here is a reduced version of the test case:

module a_mod

  type :: a
   contains
     procedure, NOPASS :: a_ass, a_ass_sv
     generic :: assignment(=) => a_ass, a_ass_sv
  end type

contains

  impure elemental subroutine a_ass (out, in)
    class(a), intent(out) :: out
    type(a), intent(in)   :: in
  end subroutine

  subroutine a_ass_sv (out, in)
    class(a), intent(out) :: out(:)
    type(a), intent(in)   :: in
  end subroutine

end module
Comment 2 janus 2012-09-15 18:46:06 UTC
Note: The same error appears also for a non-typebound generic interface:


module a_mod

  type :: a
  end type

  interface ass
    procedure :: a_ass, a_ass_sv
  end interface  

contains

  impure elemental subroutine a_ass (out, in)
    class(a), intent(out) :: out
    type(a), intent(in)   :: in
  end subroutine

  subroutine a_ass_sv (out, in)
    class(a), intent(out) :: out(:)
    type(a), intent(in)   :: in
  end subroutine

end module
Comment 3 janus 2012-09-15 20:05:53 UTC
(In reply to comment #2)
> Note: The same error appears also for a non-typebound generic interface:

... also if the second argument 'in' is removed from both procedures.

However, the test case is accepted if the CLASS declarations are changed to TYPE:


module a_mod

  type :: a
  end type

  interface ass
    procedure :: a_ass, a_ass_sv
  end interface  

contains

  impure elemental subroutine a_ass (out)
    type(a), intent(out) :: out
  end subroutine

  subroutine a_ass_sv (out)
    type(a), intent(out) :: out(:)
  end subroutine

end module
Comment 4 janus 2012-09-15 21:02:17 UTC
Apparently the problem is that gfc_compare_types does not handle CLASS arrays properly. The following patch should fix it (it makes gfortran accept the test case):


Index: gcc/fortran/interface.c
===================================================================
--- gcc/fortran/interface.c	(revision 191303)
+++ gcc/fortran/interface.c	(working copy)
@@ -507,14 +507,18 @@ gfc_compare_types (gfc_typespec *ts1, gfc_typespec
 static int
 compare_type_rank (gfc_symbol *s1, gfc_symbol *s2)
 {
+  gfc_array_spec *as1, *as2;
   int r1, r2;
 
-  r1 = (s1->as != NULL) ? s1->as->rank : 0;
-  r2 = (s2->as != NULL) ? s2->as->rank : 0;
+  as1 = (s1->ts.type == BT_CLASS) ? CLASS_DATA (s1)->as : s1->as;
+  as2 = (s2->ts.type == BT_CLASS) ? CLASS_DATA (s2)->as : s2->as;
 
+  r1 = as1 ? as1->rank : 0;
+  r2 = as2 ? as2->rank : 0;
+
   if (r1 != r2
-      && (!s1->as || s1->as->type != AS_ASSUMED_RANK)
-      && (!s2->as || s2->as->type != AS_ASSUMED_RANK))
+      && (!as1 || as1->type != AS_ASSUMED_RANK)
+      && (!as2 || as2->type != AS_ASSUMED_RANK))
     return 0;			/* Ranks differ.  */
 
   return gfc_compare_types (&s1->ts, &s2->ts)



Regtesting now ...
Comment 5 janus 2012-09-15 21:53:49 UTC
(In reply to comment #4)
> Regtesting now ...

... finished without failures.
Comment 6 Dominique d'Humieres 2012-09-16 18:26:28 UTC
With the patch at http://gcc.gnu.org/ml/fortran/2012-09/msg00051.html, the tests in comments #0 and #1 fails with

pr54594_1.f90:6.32:

     generic :: assignment(=) => a_ass
                                1
Error: Type-bound operator at (1) can't be NOPASS

Is it expected?
Comment 7 janus 2012-09-16 20:49:24 UTC
Author: janus
Date: Sun Sep 16 20:49:20 2012
New Revision: 191365

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=191365
Log:
2012-09-16  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/54594
	* interface.c (compare_type_rank): Handle CLASS arrays.

2012-09-16  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/54594
	* gfortran.dg/typebound_generic_14.f03: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/typebound_generic_14.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/interface.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 janus 2012-09-16 21:07:23 UTC
(In reply to comment #6)
> With the patch at http://gcc.gnu.org/ml/fortran/2012-09/msg00051.html, the
> tests in comments #0 and #1 fails with
> 
> pr54594_1.f90:6.32:
> 
>      generic :: assignment(=) => a_ass
>                                 1
> Error: Type-bound operator at (1) can't be NOPASS
> 
> Is it expected?

That's a good question. I could not find that restriction in the standard on a quick check. In any case, the error message comes from 'get_checked_tb_operator_target' (resolve.c), which was committed in r150856 for PR 37435.
Comment 9 Tobias Burnus 2012-09-16 21:25:18 UTC
(In reply to comment #8)
> > Is it expected?

(Both the original example and the one of comment 1 do compile and run with crayftn.)


> That's a good question. I could not find that restriction in the standard on a
> quick check. In any case, the error message comes from
> 'get_checked_tb_operator_target' (resolve.c), which was committed in r150856

That's PR 37425  (you had one digit wrong).


The constraint is (F2008):

C468 (R450) If generic-spec is not generic-name, each of its specific bindings shall have a passed-object dummy argument (4.5.4.5).

with

R1207 generic-spec  is  generic-name
                    or  OPERATOR ( dened-operator )
                    or  ASSIGNMENT ( = )
                    or  defined-io-generic-spec
Comment 10 janus 2012-09-16 21:38:23 UTC
(In reply to comment #9)
> The constraint is (F2008):
> 
> C468 (R450) If generic-spec is not generic-name, each of its specific bindings
> shall have a passed-object dummy argument (4.5.4.5).
> 
> with
> 
> R1207 generic-spec  is  generic-name
>                     or  OPERATOR ( dened-operator )
>                     or  ASSIGNMENT ( = )
>                     or  defined-io-generic-spec

Thanks for finding the reference. I looked in the right spot, but somehow overread it, due to the 'indirect' wording.

I will commit the following docu-patch as obvious:

Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c       (revision 191364)
+++ gcc/fortran/resolve.c       (working copy)
@@ -11429,7 +11429,7 @@
   target_proc = target->specific->u.specific->n.sym;
   gcc_assert (target_proc);
 
-  /* All operator bindings must have a passed-object dummy argument.  */
+  /* F08:C468. All operator bindings must have a passed-object dummy argument.  */
   if (target->specific->nopass)
     {
       gfc_error ("Type-bound operator at %L can't be NOPASS", &where);
Comment 11 janus 2012-09-16 22:04:30 UTC
Author: janus
Date: Sun Sep 16 22:04:26 2012
New Revision: 191366

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=191366
Log:
2012-09-16  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/54594
	* resolve.c (get_checked_tb_operator_target): Add a reference to the
	relevant quote from the F08 standard.

Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
Comment 12 janus 2012-09-16 22:06:30 UTC
(In reply to comment #6)
> Error: Type-bound operator at (1) can't be NOPASS
> 
> Is it expected?

After this is settled (the answer being yes), I'll close this PR, since the original problem was fixed with r191365.