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.