https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80850

Paul Thomas <pault at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|WAITING                     |NEW
                 CC|                            |pault at gcc dot gnu.org

--- Comment #13 from Paul Thomas <pault at gcc dot gnu.org> ---
(In reply to DIL from comment #12)
> Could you please tell me if there is a way I can check whether the
> dissociated unlimited polymorphic pointer (class(*), pointer), which is set
> to NULL, is indeed set to a clean state internally? That is, could you
> please tell me the size and structure of the internal representation of a
> class(*) pointer and what the proper values of those components would be
> when the pointer is set to NULL()? I am still trying to understand why the
> sourced allocate() statement sees that pointer as ALLOCATED. Basically, I
> want to inspect the internal state of the class(*) NULL pointer to make sure
> that the problem indeed occurs inside the sourced allocate() statement.
> Thanks!

On my system FC23 & GNU Fortran (GCC) 7.2.1 20171028 the DEV version fails
every time and makes such a mess of the system that I have had to insert a STOP
when the failed allocation is detected.

I cannot persuade the OPT version to fail at all.

The code generated for:
         clone=>NULL()
         allocate(clone,SOURCE=object,STAT=errc,ERRMSG=errmesg)

(compile with -fdump-tree-original. The output is in the OBJ directory in the
file st_stubs.F90.*.original)
____________________________________________________________________________
in the DEV version is:

    clone._vptr = (struct __vtype__STAR * {ref-all}) &__vtab__STAR;
    clone._len = 0;
    clone._data = 0B;
    stat.170 = 0;
    clone._data = __builtin_malloc (((struct __class__STAR_t *) object)->_len >
0 ? MAX_EXPR <(unsigned long) ((sizetype) ((struct __class__STAR_t *)
object)->_vptr->_size * (sizetype) ((struct __class__STAR_t *) object)->_len),
1> : MAX_EXPR <(unsigned long) ((struct __class__STAR_t *)
object)->_vptr->_size, 1>);
    if (clone._data == 0B)
      {
        stat.170 = 5014;
      }
    if (stat.170 != 0) goto L.195;
    clone._len = ((struct __class__STAR_t *) object)->_len;
    clone._vptr = object->_vptr;
    clone._len = object->_len;
    if (object->_len > 0)
      {
        clone._vptr->_copy (object->_data, clone._data, object->_len,
clone._len);
      }
    else
      {
        clone._vptr->_copy (object->_data, clone._data);
      }
    L.195:;
    if (stat.170 != 0)
      {
        ERRMSG.171 = &"Attempt to allocate an allocated object"[1]{lb: 1 sz:
1};
        __builtin_memmove ((void *) &errmesg, (void *) ERRMSG.171, 39);
        __builtin_memset ((void *) &errmesg + 39, 32, 217);
      }
    errc = stat.170;
____________________________________________________________________________
and in the OPT version is:

    clone._vptr = (struct __vtype__STAR * {ref-all}) &__vtab__STAR;
    clone._len = 0;
    clone._data = 0B;
    stat.170 = 0;
    clone._data = __builtin_malloc (((struct __class__STAR_t *) object)->_len >
0 ? MAX_EXPR <(unsigned long) ((sizetype) ((struct __class__STAR_t *)
object)->_vptr->_size * (sizetype) ((struct __class__STAR_t *) object)->_len),
1> : MAX_EXPR <(unsigned long) ((struct __class__STAR_t *)
object)->_vptr->_size, 1>);
    if ((logical(kind=1)) __builtin_expect ((integer(kind=8)) (clone._data ==
0B), 0, 40))
      {
        stat.170 = 5014;
      }
    if ((logical(kind=1)) __builtin_expect ((integer(kind=8)) (stat.170 != 0),
0, 40)) goto L.216;
    clone._len = ((struct __class__STAR_t *) object)->_len;
    clone._vptr = object->_vptr;
    clone._len = object->_len;
    if (object->_len > 0)
      {
        clone._vptr->_copy (object->_data, clone._data, object->_len,
clone._len);
      }
    else
      {
        clone._vptr->_copy (object->_data, clone._data);
      }
    L.216:;
    if (stat.170 != 0)
      {
        ERRMSG.171 = &"Attempt to allocate an allocated object"[1]{lb: 1 sz:
1};
        __builtin_memmove ((void *) &errmesg, (void *) ERRMSG.171, 39);
        __builtin_memset ((void *) &errmesg + 39, 32, 217);
      }
    errc = stat.170;
____________________________________________________________________________


The only difference is that the OPT version uses __builtin_expect in the
conditions.

A slightly perplexing thing to note is that the message is wrong for the test
that is done. clone._data is being allocated before the test to check if it is
NULL. Thus, it is the operating system that is coming back with the NULL, which
likely to be due to a lack of memory. Setting the stack size using ulimit
doesn't seem to make any difference, which leaves me at a bit of a loss.

On the other hand compiling with -fno-automatic seems to fix the problem,
although the entire source needs this and not just ststubs.F90, Your workaround
effects the same thing by using a module variable.

I'll keep on with this but have to take a break for a day or so.

Cheers

Paul

Reply via email to