Bug 57553 - [F08] Valid use of STORAGE_SIZE rejected, bad error message for invalid use
Summary: [F08] Valid use of STORAGE_SIZE rejected, bad error message for invalid use
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic, rejects-valid
Depends on:
Blocks:
 
Reported: 2013-06-07 07:43 UTC by Tobias Burnus
Modified: 2019-02-27 19:52 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-06-29 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2013-06-07 07:43:00 UTC
Found at http://mailman.j3-fortran.org/pipermail/j3/2013-June/006442.html (please read also follow up email).


* The following looks valid to me and it is rejected with a bogus error message:
  integer, parameter :: ESize = storage_size('a')
                                              1
  Error: Invalid character in name at (1)

integer, parameter :: ESize = storage_size('a')
end


* The following is invalid, but the error message location is bad:
    integer, parameter :: ESize = ( storage_size(a) + 7 ) / 8
    1
  Error: Unclassifiable statement at (1)

subroutine S ( A )
  character(len=*), intent(in) :: A
  integer, parameter :: ESize = ( storage_size(a) + 7 ) / 8
end
Comment 1 Tobias Burnus 2013-06-07 07:46:19 UTC
"13.7.160 STORAGE SIZE (A [, KIND])
 Description. Storage size in bits.
 Class. Inquiry function.
 Arguments.
 A     shall be a scalar or array of any type. If it is polymorphic it shall
       not be an undefined pointer. If it has any deferred type parameters
       it shall not be an unallocated allocatable variable or a disassociated
       or undefined pointer."

My impression is that the current code assumes that the argument is a variable and not an expression (including literal constants).
Comment 2 Tobias Burnus 2013-06-08 12:22:38 UTC
Author: burnus
Date: Sat Jun  8 12:21:58 2013
New Revision: 199850

URL: http://gcc.gnu.org/viewcvs?rev=199850&root=gcc&view=rev
Log:
2013-06-08  Tobias Burnus  <burnus@net-b.de>

        PR fortran/57553
        * simplify.c (gfc_simplify_storage_size): Handle literal
        strings.
        * trans-intrinsic.c (gfc_conv_intrinsic_storage_size):
        Add missing fold_convert.

2013-06-08  Tobias Burnus  <burnus@net-b.de>

        PR fortran/57553
        * gfortran.dg/storage_size_4.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/storage_size_4.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/simplify.c
    trunk/gcc/fortran/trans-intrinsic.c
    trunk/gcc/testsuite/ChangeLog
Comment 3 Tobias Burnus 2013-06-08 12:24:52 UTC
The rejects-valid and the ICE-on-valid-code issue has been solved.


TODO: The following message for invalid code should be improved. [The problem is that storage_size cannot handle "a", which is required for a constant expression.]

    integer, parameter :: ESize = ( storage_size(a) + 7 ) / 8
    1
  Error: Unclassifiable statement at (1)
Comment 4 Dominique d'Humieres 2013-06-29 15:24:20 UTC
> TODO: The following message for invalid code should be improved. ...

Confirmed.
Comment 5 Harald Anlauf 2016-02-09 21:11:42 UTC
(In reply to Tobias Burnus from comment #3)
> The rejects-valid and the ICE-on-valid-code issue has been solved.
> 
> 
> TODO: The following message for invalid code should be improved. [The
> problem is that storage_size cannot handle "a", which is required for a
> constant expression.]
> 
>     integer, parameter :: ESize = ( storage_size(a) + 7 ) / 8
>     1
>   Error: Unclassifiable statement at (1)

It appears that check_inquiry() does not recognize storage_size
as an intrinsic.

The patch below turns the error message (for -std=gnu/f2008) into:

pr57553.f90:4:45:

   integer, parameter :: ESize = storage_size(a)
                                             1
Error: Parameter 'a' at (1) has not been declared or is a variable, which does not reduce to a constant expression


Index: gcc/fortran/expr.c
===================================================================
--- gcc/fortran/expr.c	(revision 233203)
+++ gcc/fortran/expr.c	(working copy)
@@ -2264,6 +2264,15 @@
     "new_line", NULL
   };
 
+  /* std=f2008+ or -std=gnu */
+  static const char *const inquiry_func_gnu[] = {
+    "lbound", "shape", "size", "ubound",
+    "bit_size", "len", "kind",
+    "digits", "epsilon", "huge", "maxexponent", "minexponent",
+    "precision", "radix", "range", "tiny",
+    "new_line", "storage_size", NULL
+  };
+
   int i = 0;
   gfc_actual_arglist *ap;
 
@@ -2290,8 +2299,11 @@
     {
       name = e->symtree->n.sym->name;
 
+      functions = inquiry_func_gnu;		/* std=f2008+ or -std=gnu */
       functions = (gfc_option.warn_std & GFC_STD_F2003)
-		? inquiry_func_f2003 : inquiry_func_f95;
+		? inquiry_func_f2003 : functions;
+      functions = (gfc_option.warn_std & GFC_STD_F95)
+		? inquiry_func_f95 : functions;
 
       for (i = 0; functions[i]; i++)
 	if (strcmp (functions[i], name) == 0)
Comment 6 Harald Anlauf 2016-02-12 23:29:18 UTC
(In reply to Harald Anlauf from comment #5)

I think I mixed up gfc_option.warn_std and gfc_option.allow_std
in the previous patch.  A revised version follows:

Index: gcc/fortran/expr.c
===================================================================
--- gcc/fortran/expr.c	(revision 233388)
+++ gcc/fortran/expr.c	(working copy)
@@ -2264,6 +2264,15 @@
     "new_line", NULL
   };
 
+  /* std=f2008+ or -std=gnu */
+  static const char *const inquiry_func_gnu[] = {
+    "lbound", "shape", "size", "ubound",
+    "bit_size", "len", "kind",
+    "digits", "epsilon", "huge", "maxexponent", "minexponent",
+    "precision", "radix", "range", "tiny",
+    "new_line", "storage_size", NULL
+  };
+
   int i = 0;
   gfc_actual_arglist *ap;
 
@@ -2290,8 +2299,11 @@
     {
       name = e->symtree->n.sym->name;
 
-      functions = (gfc_option.warn_std & GFC_STD_F2003)
+      /* Choose appropriate set.  Note that -std=gnu is std=f2008+ */
+      functions = (gfc_option.allow_std & GFC_STD_F2003)
 		? inquiry_func_f2003 : inquiry_func_f95;
+      functions = (gfc_option.allow_std & GFC_STD_F2008)
+		? inquiry_func_gnu : functions;
 
       for (i = 0; functions[i]; i++)
 	if (strcmp (functions[i], name) == 0)
Comment 7 Harald Anlauf 2019-01-22 21:19:16 UTC
Patch submitted for review:

https://gcc.gnu.org/ml/fortran/2019-01/msg00201.html
Comment 8 anlauf 2019-01-26 20:46:27 UTC
Author: anlauf
Date: Sat Jan 26 20:45:55 2019
New Revision: 268303

URL: https://gcc.gnu.org/viewcvs?rev=268303&root=gcc&view=rev
Log:
2019-01-26  Harald Anlauf  <anlauf@gmx.de>

	PR fortran/57553
	* expr.c (check_inquiry): Add list of inquiry functions allowed in
	constant expressions for F2008+.

2019-01-26  Harald Anlauf  <anlauf@gmx.de>

	PR fortran/57553
	* gfortran.dg/pr57553.f90: New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/pr57553.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/expr.c
    trunk/gcc/testsuite/ChangeLog
Comment 9 anlauf 2019-02-27 19:52:19 UTC
Fixed.