aboutsummaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorHarald Anlauf <anlauf@gmx.de>2023-12-18 18:59:02 +0100
committerHarald Anlauf <anlauf@gmx.de>2023-12-18 20:32:52 +0100
commitb77691a90fc8a7e917417ce747bf78669304f951 (patch)
tree7a6a27ed6db2d95f978d35dd58107aa204b6a1e4 /libgfortran
parentf85fdf59c91fe4aa56633347268d144d3e075844 (diff)
downloadgcc-b77691a90fc8a7e917417ce747bf78669304f951.zip
gcc-b77691a90fc8a7e917417ce747bf78669304f951.tar.gz
gcc-b77691a90fc8a7e917417ce747bf78669304f951.tar.bz2
Fortran: update DATE_AND_TIME intrinsic for Fortran 2018 [PR96580]
Fortran 2018 allows a non-default integer kind for its VALUES argument if it has a decimal exponent range of at least four. Update checks, library implementation and documentation. gcc/fortran/ChangeLog: PR fortran/96580 * check.cc (array_size_check): New helper function. (gfc_check_date_and_time): Use it for checking minimum size of VALUES argument. Update kind check to Fortran 2018. * intrinsic.texi: Fix documentation of DATE_AND_TIME. libgfortran/ChangeLog: PR fortran/96580 * intrinsics/date_and_time.c (date_and_time): Handle VALUES argument for kind=2 and kind=16 (if available). gcc/testsuite/ChangeLog: PR fortran/96580 * gfortran.dg/date_and_time_2.f90: New test. * gfortran.dg/date_and_time_3.f90: New test. * gfortran.dg/date_and_time_4.f90: New test.
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/intrinsics/date_and_time.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/libgfortran/intrinsics/date_and_time.c b/libgfortran/intrinsics/date_and_time.c
index 681a815..929bbdc 100644
--- a/libgfortran/intrinsics/date_and_time.c
+++ b/libgfortran/intrinsics/date_and_time.c
@@ -209,20 +209,20 @@ date_and_time (char *__date, char *__time, char *__zone,
delta = 1;
if (unlikely (len < VALUES_SIZE))
- runtime_error ("Incorrect extent in VALUE argument to"
+ runtime_error ("Incorrect extent in VALUES argument to"
" DATE_AND_TIME intrinsic: is %ld, should"
" be >=%ld", (long int) len, (long int) VALUES_SIZE);
/* Cope with different type kinds. */
if (elt_size == 4)
- {
+ {
GFC_INTEGER_4 *vptr4 = __values->base_addr;
for (i = 0; i < VALUES_SIZE; i++, vptr4 += delta)
*vptr4 = values[i];
}
else if (elt_size == 8)
- {
+ {
GFC_INTEGER_8 *vptr8 = (GFC_INTEGER_8 *)__values->base_addr;
for (i = 0; i < VALUES_SIZE; i++, vptr8 += delta)
@@ -233,6 +233,32 @@ date_and_time (char *__date, char *__time, char *__zone,
*vptr8 = values[i];
}
}
+ else if (elt_size == 2)
+ {
+ GFC_INTEGER_2 *vptr2 = (GFC_INTEGER_2 *)__values->base_addr;
+
+ for (i = 0; i < VALUES_SIZE; i++, vptr2 += delta)
+ {
+ if (values[i] == - GFC_INTEGER_4_HUGE)
+ *vptr2 = - GFC_INTEGER_2_HUGE;
+ else
+ *vptr2 = (GFC_INTEGER_2) values[i];
+ }
+ }
+#if defined (HAVE_GFC_INTEGER_16)
+ else if (elt_size == 16)
+ {
+ GFC_INTEGER_16 *vptr16 = (GFC_INTEGER_16 *)__values->base_addr;
+
+ for (i = 0; i < VALUES_SIZE; i++, vptr16 += delta)
+ {
+ if (values[i] == - GFC_INTEGER_4_HUGE)
+ *vptr16 = - GFC_INTEGER_16_HUGE;
+ else
+ *vptr16 = values[i];
+ }
+ }
+#endif
else
abort ();
}