Thanks for the patch, here is a first but incomplete review. I think the patch looks mostly okay.

Running your test cases through crayftn, I found:

  if (SAME_TYPE_AS (obj1, u1) .neqv. .FALSE.) call abort
                          ^
ftn-1698 crayftn: ERROR $MAIN, File = unlimited_polymorphic_1.f03, Line = 67, Column = 27 Type INTEGER(kind=4) is not allowed for the "B" argument of intrinsic SAME_TYPE_AS.

The message itself is correct. However, Paul mentioned off-list that "obj1" and "u1" are both extensible types and, hence, neither is an "integer(kind=4)". In any case, if either of them were an integer(4) it would be invalid:

From Fortran 2008's "13.7.142 SAME_TYPE_AS (A, B)"
"Arguments.
"A shall be an object of extensible declared type or unlimited polymorphic. If it is a pointer, it shall not have an undefined association status. "B shall be an object of extensible declared type or unlimited polymorphic. If it is a pointer, it shall
not have an undefined association status."

Ditto for "13.7.60 EXTENDS TYPE OF (A, MOLD)".

At least for -std=f2003/f2008 we have to reject nonextensible, non-unlimited-polymorphic arguments. - Even if a supporting intrinsic types were a nice addition.


Paul Richard Thomas wrote:
+
+       if (UNLIMITED_POLY (c->expr))
+       {
+         gfc_error ("F08: C4106 array constructor value at %L shall not be "
+                    " unlimited polymorphic", &c->expr->where);
+         t = FAILURE;

You have a " " at both then end and the beginning of the line. Additionally, I wonder how we want to inform the user about those constrains. So far, we always had the message only without reference to the standard. Having one, is not bad, the question is only where. I would favor to have the information at the end, given that gfortran currently prints "Fortran 2008:" if a something is only valid in Fortran 2008 and later. Additionally, I personally don't like "F08" that much and prefer "Fortran 2008" (or at least "F2008"). Thus, I'd use something like:

+         gfc_error ("Array constructor value at %L shall not be unlimited"
+                    " polymorphic [Fortran 2008, C4106]", &c->expr->where);


(Except for the double " ", that's bikeshadding; hence, I leave it to you. The "F08: C..." also occures at other places in the patch)



+    sprintf (dt_name, "%s", "$tar");

(Off-topic question for mere curiosity: Why "$tar"?)

+ gfc_find_intrinsic_vtab (gfc_typespec *ts)

+   if (ts->type == BT_CHARACTER && ts->deferred)
+     {
+       gfc_error ("TODO: Deferred character length variable at %C cannot "
+                "yet be associated with unlimited polymorphic entities");

The same issue also applies to assumed-length strings. At least the following program prints:
           0 ""
           0 ""
I think we have to fill a PR which lists all of the known deficits of the current implementation. Besides the string issue, that's also the renaming of gfc_find_intrinsic_vtab into gfc_find_derived_vtab.

Here's the test case:

call foo("Hello")
call foo("World!")
contains
subroutine foo(str)
  character(len=*), target :: str
  class(*), pointer :: up
  up => str
  call bar(up)
end subroutine foo
subroutine bar(x)
  class(*) :: x

  select type(x)
    type is (character(len=*))
      print *, len(x), '"'//x//'"'
  end select
end subroutine bar
end



+ #define UNLIMITED_POLY(sym) (sym != NULL && sym->ts.type == BT_CLASS && 
CLASS_DATA (sym) \
+                       && CLASS_DATA (sym)->ts.u.derived \
+                       && CLASS_DATA 
(sym)->ts.u.derived->attr.unlimited_polymorphic)

The lines are way too long: 90 and 86 characters.


+   sprintf (name, "__tmp_%s_%d", gfc_basic_typename (ts->type),
+          ts->type == BT_CHARACTER ? charlen : ts->kind);

How do you distinguish between character(kind=1) and character(kind=4)? The same issue exists for a like-wise code in resolve_select_type.


+  /* Unlimited polymorphic pointers should have their vptr nullified.  */
+  if (UNLIMITED_POLY (sym) && CLASS_DATA (sym)->attr.pointer)
+    gfc_defer_symbol_init (sym);


Why? If the pointer has never been pointer-associated, one shouldn't access it. Thus, the code is not need. If it is needed, I fear that code will also break when one later deallocates/nullifies the pointer. I think _vptr should only be set when also nonpolymorphic CLASS get their _vptr set. For pointers, that's presumably only ALLOCATE and pointer-association.


Tobias

Reply via email to