Bug 48958 - Add runtime diagnostics for SIZE intrinsic function
Summary: Add runtime diagnostics for SIZE intrinsic function
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.7.0
: P5 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-11 07:51 UTC by Thomas Henlich
Modified: 2020-11-16 22:31 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-10-14 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Henlich 2011-05-11 07:51:13 UTC
As has been brought up before (Bug 20406), the SIZE intrinsic returns an unpredictable result if the argument is an unallocated allocatable or a pointer that is not associated.

While this is perfectly standard-conforming behaviour, it would be helpful in program development to have SIZE throw a runtime error if this condition occurs.

I.e. SIZE should first check if an array is ALLOCATED or a pointer is ASSOCIATED and abort with a runtime error if that is not the case.

Fortran 2008:

13.7.156 SIZE (ARRAY [, DIM, KIND])
3 Arguments.
ARRAY shall be an array of any type. It shall not be an unallocated allocatable variable or a pointer that is not associated. If ARRAY is an assumed-size array, DIM shall be present with a value less than the rank of ARRAY.
Comment 1 Dominique d'Humieres 2015-10-14 18:57:58 UTC
PR20406 has been closed as WONTFIX, any reason to keep this PR opened?
Comment 2 Harald Anlauf 2015-10-14 21:45:12 UTC
There are a few inquiry functions (SIZE, SHAPE, (L,U)BOUND) where such
a diagnostic might be useful.  It could be hidden behind one of the
-fcheck options.

However:

Depending on the implementation, it might work only for ALLOCATABLE,
where there is no undefined allocation status.  For a POINTER, the
status could be undefined, and it is not possible to discover this.
(It is even nice to be able to find out what the last size was
before deallocating the target of the pointer...)

NAG does the following:

% cat pr48958.f90
!integer, allocatable :: a(:)
integer, pointer :: a(:)
print *, size (a)
end
% nagfor -C pr48958.f90 && ./a.out 
NAG Fortran Compiler Release 5.3.1(907)
[NAG Fortran Compiler normal termination]
Runtime Error: pr48958.f90, line 3: Reference to undefined POINTER A
Program terminated by fatal error
Abort

Not sure whether there are other compilers which can handle this.
Comment 3 Dominique d'Humieres 2015-10-15 09:36:12 UTC
This PR is related to pr46182. While I agree that it would be nice to have run time errors for invalid use of unallocated variables/not associated pointers, I doubt it will ever happen.
Comment 4 Eric Gallager 2017-08-03 19:10:31 UTC
(In reply to Dominique d'Humieres from comment #3)
> This PR is related to pr46182. While I agree that it would be nice to have
> run time errors for invalid use of unallocated variables/not associated
> pointers, I doubt it will ever happen.

That sounds more like a case for the SUSPENDED status than WAITING
Comment 5 anlauf 2020-11-14 22:16:25 UTC
Incomplete patch: https://gcc.gnu.org/pipermail/fortran/2020-November/055300.html
Comment 6 GCC Commits 2020-11-16 21:01:20 UTC
The master branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:0c81ccc3d87098b93b0e6a2dd76815e4d6e78ff0

commit r11-5064-g0c81ccc3d87098b93b0e6a2dd76815e4d6e78ff0
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Mon Nov 16 22:00:58 2020 +0100

    PR fortran/48958 - Add runtime diagnostics for SIZE intrinsic function
    
    Add code for runtime checking of status of ALLOCATABLE and POINTER
    arguments to the SIZE intrinsic when -fcheck=pointer is specified.
    
    gcc/fortran/ChangeLog:
    
            * trans-intrinsic.c (gfc_conv_intrinsic_size): Generate runtime
            checking code for status of argument.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/pr48958.f90: New test.
Comment 7 anlauf 2020-11-16 22:31:12 UTC
The question on what to do with runtime checks and possibly undefined pointers,
which has been repeated by Thomas on the ML, could be solved by initializing
the data component when -fcheck=pointer is specified.

A somewhat hackish solution which regtests cleanly:

diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index b2c39aa32de..6e1f27ead45 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -10668,7 +10668,9 @@ gfc_trans_deferred_array (gfc_symbol * sym, gfc_wrapped_block * block)
     }
 
   /* NULLIFY the data pointer, for non-saved allocatables.  */
-  if (GFC_DESCRIPTOR_TYPE_P (type) && !sym->attr.save && sym->attr.allocatable)
+  if (GFC_DESCRIPTOR_TYPE_P (type) && !sym->attr.save
+      && (sym->attr.allocatable
+         || (sym->attr.pointer && (gfc_option.rtcheck & GFC_RTCHECK_POINTER))))
     {
       gfc_conv_descriptor_data_set (&init, descriptor, null_pointer_node);
       if (flag_coarray == GFC_FCOARRAY_LIB && sym->attr.codimension)

Still need to learn weather this is the right solution, but it does the job.