From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by sourceware.org (Postfix) with ESMTPS id 7C49E3858420; Thu, 16 Dec 2021 14:49:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7C49E3858420 Received: by mail-wm1-x32e.google.com with SMTP id b73so3625163wmd.0; Thu, 16 Dec 2021 06:49:11 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:mime-version:subject:message-id:date:cc:to; bh=zP3dskVQhbZqmWlMGPsfkjklukykKzHFxr9EvFy0tyY=; b=27R7gCBGRcG9byCF63omhMFc0XTFjRc+YKCABIc1Ks9DGvSZTKhsTGCdCIwP6mbzoh zNh+BiSdADgd38+7qfOEtP8EDxDpzz2H0M3uRBSuLjM3jbsTmjs3P5z6t8b655oPp0ap UxeUYgbqtdVBFayHmDCtD6pcR7PYpj4J9d7iG2q3cPOOAzuddNQc/fxojkRlEA2tUqYz lz0uKIRoRSzzkxzxDCmPcBQ1dqTQsAsGtAShyDNJ2wSJI549HuYH3JgXkaqGxuyQ3tv2 RXWfE4TzaEvLyItQD9bfvFe+2fTJMMJRwmlyqrP2N/wm373zreXuh8a9JvZGbu9hwJqO pasQ== X-Gm-Message-State: AOAM532FqK/BIKMyauq9pcN75wc4FE2cnKbhQeqxgCMyERzn1mD/VmnO oQQ90czcAO13eedPqIHAl7zUoJ324Io= X-Google-Smtp-Source: ABdhPJwZ/dx/f8x7DdxIgxqKlutNX1M88jm9dWDRs0Dc8879yQA4vYj+8YHVwBEOkFqdHISXXhC0Rg== X-Received: by 2002:a05:600c:3d94:: with SMTP id bi20mr5336959wmb.71.1639666150643; Thu, 16 Dec 2021 06:49:10 -0800 (PST) Received: from smtpclient.apple (chp127.enscp.fr. [193.51.253.127]) by smtp.gmail.com with ESMTPSA id c11sm1762855wmq.48.2021.12.16.06.49.10 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 Dec 2021 06:49:10 -0800 (PST) From: FX Content-Type: multipart/mixed; boundary="Apple-Mail=_3030A3FB-FE79-47AC-8EF9-EF2AC097CBC0" Mime-Version: 1.0 (Mac OS X Mail 15.0 \(3693.40.0.1.81\)) Subject: [patch] Fix libfortran/101255, wrong IOSTAT value for FLUSH Message-Id: <257551D4-BDAE-48D1-A91B-D2C59CC6CD96@gmail.com> Date: Thu, 16 Dec 2021 15:49:09 +0100 Cc: gcc-patches@gcc.gnu.org To: fortran@gcc.gnu.org X-Mailer: Apple Mail (2.3693.40.0.1.81) X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Dec 2021 14:49:12 -0000 --Apple-Mail=_3030A3FB-FE79-47AC-8EF9-EF2AC097CBC0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=us-ascii Hi, Bug reported by Tobias at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101255 Trivial fix, adding a testcase. Bootstrapped and regtested on x86_64-pc-linux-gnu. OK to commit? FX --Apple-Mail=_3030A3FB-FE79-47AC-8EF9-EF2AC097CBC0 Content-Disposition: attachment; filename=pr98507.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="pr98507.patch" Content-Transfer-Encoding: 7bit commit 81631ceaccf9c170e547e06f94c2e8a9e644134c Author: Francois-Xavier Coudert Date: 2021-12-16 12:40:03 +0100 Fix timezone handling near year boundaries PR libfortran/98507 libgfortran/ChangeLog: * intrinsics/time_1.h: Prefer clock_gettime() over gettimeofday(). * intrinsics/date_and_time.c: Fix timezone wrapping. gcc/testsuite/ChangeLog: * gfortran.dg/date_and_time_1.f90: New file. diff --git a/gcc/testsuite/gfortran.dg/date_and_time_1.f90 b/gcc/testsuite/gfortran.dg/date_and_time_1.f90 new file mode 100644 index 00000000000..0cd0c390d8c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/date_and_time_1.f90 @@ -0,0 +1,35 @@ +! PR libfortran/98507 +! { dg-do run } + +program demo_time_and_date + implicit none + character(8) :: date + character(10) :: time + character(5) :: zone + integer :: val(8) + integer :: h, m + + call date_and_time(values=val) + + if (val(1) < 2000 .or. val(1) > 2100) call abort + if (val(2) < 1 .or. val(2) > 12) call abort + if (val(3) < 1 .or. val(3) > 31) call abort + + ! Maximum offset is 14 hours (UTC+14) + if (val(4) < -14*60 .or. val(4) > 14*60) call abort + + if (val(5) < 0 .or. val(5) > 23) call abort + if (val(6) < 0 .or. val(6) > 59) call abort + if (val(7) < 0 .or. val(7) > 60) call abort + if (val(8) < 0 .or. val(8) > 999) call abort + + call date_and_time(zone=zone) + if (len(zone) /= 0) then + ! If ZONE is present, it should present the same information as + ! given in VALUES(4) + if (len(zone) /= 5) call abort + read(zone(1:3),*) h + read(zone(4:5),*) m + if (val(4) /= 60*h+m) call abort + endif +end diff --git a/libgfortran/intrinsics/date_and_time.c b/libgfortran/intrinsics/date_and_time.c index 8213127ec95..de40bbc964e 100644 --- a/libgfortran/intrinsics/date_and_time.c +++ b/libgfortran/intrinsics/date_and_time.c @@ -113,9 +113,6 @@ gmtime_r (const time_t * timep, struct tm * result) VALUES for INTEGER(kind=4) and INTEGER(kind=8). Based on libU77's date_time_.c. - - TODO : - - Check year boundaries. */ #define DATE_LEN 8 #define TIME_LEN 10 @@ -131,7 +128,7 @@ date_and_time (char *__date, char *__time, char *__zone, gfc_array_i4 *__values, GFC_INTEGER_4 __date_len, GFC_INTEGER_4 __time_len, GFC_INTEGER_4 __zone_len) { - int i; + int i, delta_day; char date[DATE_LEN + 1]; char timec[TIME_LEN + 1]; char zone[ZONE_LEN + 1]; @@ -154,9 +151,22 @@ date_and_time (char *__date, char *__time, char *__zone, values[0] = 1900 + local_time.tm_year; values[1] = 1 + local_time.tm_mon; values[2] = local_time.tm_mday; - values[3] = (local_time.tm_min - UTC_time.tm_min + - 60 * (local_time.tm_hour - UTC_time.tm_hour + - 24 * (local_time.tm_yday - UTC_time.tm_yday))); + + /* Day difference with UTC should always be -1, 0 or +1. + Near year boundaries, we may obtain a large positive (+364, + or +365 on leap years) or negative (-364, or -365 on leap years) + number, which we have to handle. + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98507 + */ + delta_day = local_time.tm_yday - UTC_time.tm_yday; + if (delta_day < -1) + delta_day = 1; + else if (delta_day > 1) + delta_day = -1; + + values[3] = local_time.tm_min - UTC_time.tm_min + + 60 * (local_time.tm_hour - UTC_time.tm_hour + 24 * delta_day); + values[4] = local_time.tm_hour; values[5] = local_time.tm_min; values[6] = local_time.tm_sec; diff --git a/libgfortran/intrinsics/time_1.h b/libgfortran/intrinsics/time_1.h index 2d238fd075b..b2adca0c5f3 100644 --- a/libgfortran/intrinsics/time_1.h +++ b/libgfortran/intrinsics/time_1.h @@ -213,19 +213,19 @@ gf_cputime (long *user_sec, long *user_usec, long *system_sec, long *system_usec static inline int gf_gettime (time_t * secs, long * usecs) { -#ifdef HAVE_GETTIMEOFDAY +#ifdef HAVE_CLOCK_GETTIME + struct timespec ts; + int err = clock_gettime (CLOCK_REALTIME, &ts); + *secs = ts.tv_sec; + *usecs = ts.tv_nsec / 1000; + return err; +#elif defined(HAVE_GETTIMEOFDAY) struct timeval tv; int err; err = gettimeofday (&tv, NULL); *secs = tv.tv_sec; *usecs = tv.tv_usec; return err; -#elif defined(HAVE_CLOCK_GETTIME) - struct timespec ts; - int err = clock_gettime (CLOCK_REALTIME, &ts); - *secs = ts.tv_sec; - *usecs = ts.tv_nsec / 1000; - return err; #else time_t t = time (NULL); *secs = t; --Apple-Mail=_3030A3FB-FE79-47AC-8EF9-EF2AC097CBC0--