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

kargls at comcast dot net changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kargls at comcast dot net

--- Comment #1 from kargls at comcast dot net ---
Oh my!  Damian, you really do find the odd bugs! ;-)

Reduced testcase.

  module foo
    implicit none
    type hyperparameters_t(k)
      integer, kind :: k = kind(1.)
      real(k) :: learning_rate_ = real(1.5,k)
    end type
  end module

gfortran is trying to check and reduce the initialization
expression(s) in the derived type definition.  Here, 'k' seems
to be a variable instead of a constant expression.   This 
patch gets us passed the error reported by Damian.

diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 1f170131ae1..6f5dc2f9895 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -745,8 +745,15 @@ kind_check (gfc_expr *k, int n, bt type)
       return false;
     }

-  if (gfc_extract_int (k, &kind)
-      || gfc_validate_kind (type, kind, true) < 0)
+  if (k->expr_type == EXPR_CONSTANT)
+    gfc_extract_int (k, &kind);
+  else if (k->expr_type == EXPR_VARIABLE
+          && k->symtree->n.sym->attr.pdt_kind)
+    return true;  /* We're in a derived type definition.  Punt! */
+  else
+    kind = -1;
+
+  if (kind < 0 || gfc_validate_kind (type, kind, true) < 0)
     {
       gfc_error ("Invalid kind for %s at %L", gfc_basic_typename (type),
                 &k->where);

Note, k->param_list==NULL as this is not a derived-type declaration statement.
We do find

(gdb) call debug(k)
k (INTEGER 4)
(gdb) call debug(k->symtree->n.sym)
|| symbol: 'k'            
  type spec : (INTEGER 4)
  attributes: (VARIABLE  KIND DUMMY PDT-KIND)
  value: 4

so the default initialization of 'k = 4' is available, but that
of course is not the desired value for 'type(hyperparameters_t(k=8)) :: x'.

With the above patch, we then hit a new error in reducing the initialization
expression because 'k' is marked with EXPR_VARIABLE.

% gfcx -c dw.f90
dw.f90:7:41:

    7 |     real(k) :: learning_rate_ = real(1.5,k)
      |                                         1
Error: KIND parameter of REAL at (1) must be an initialization expression


What makes this a really nasty bug is that most (all?) intrinsic 
functions that take an integer argument can be used in an 
initialization expression provided that argument is a constant
expression.  For example,

  module foo
    implicit none
    type hyperparameters_t(k)
      integer, kind :: k = kind(1.)
      real(k) :: learning_rate_ = iabs(k)
    end type
  end module

% gfcx -c dw.f90
dw.f90:7:31:
    7 |     real(k) :: learning_rate_ = iabs(k)
      |                               1
Error: Cannot convert INTEGER(4) to REAL(0) at (1)

PS: the title of the PR should be marked with [PDT] and likely
changed to reflect the actual problem the 'keyword' is not
a type-param-value (i.e., a constant expression) in the definition
of a derived type.

Reply via email to