This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: assuming signed overflow does not occur


Per request, the inlined functions

On Sat, Sep 2, 2017 at 12:59 PM, Bruce Korb <bruce.korb@gmail.com> wrote:
> I know about all these theoretical possibilities of numbers behaving
> in strange ways when arithmetic optimizations assume that signed
> overflow won't occur when they actually might. Yep, it creates subtle
> bugs. The warning is worthwhile. Still and all:
>
>     485         tvdiff = abs_tval(sub_tval(timetv, tvlast));
>     486         if (tvdiff.tv_sec != 0) {
>
> systime.c: In function 'step_systime':
> systime.c:486:5: warning: assuming signed overflow does not occur when
> simplifying conditional to constant [-Wstrict-overflow]
>
> What possible optimization might be going on to cause an overflow
> problem when I simply want to know if the "tv_sec" field is zero or
> not? (BTW, in current source, "tvdiff" is a structure that is returned
> by abs_tval())
>
> $ gcc --version
> gcc (SUSE Linux) 4.8.5
> Copyright (C) 2015 Free Software Foundation, Inc.
> This is free software; see the source for copying conditions.  There is NO
> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


/* make sure microseconds are in nominal range */
static inline struct timeval
normalize_tval(
        struct timeval  x
        )
{
        long            z;

        if (x.tv_usec < -3l * MICROSECONDS ||
            x.tv_usec >  3l * MICROSECONDS  ) {
                z = x.tv_usec / MICROSECONDS;
                x.tv_usec -= z * MICROSECONDS;
                x.tv_sec += z;
        }

        if (x.tv_usec < 0)
                do {
                        x.tv_usec += MICROSECONDS;
                        x.tv_sec--;
                } while (x.tv_usec < 0);
        else if (x.tv_usec >= MICROSECONDS)
                do {
                        x.tv_usec -= MICROSECONDS;
                        x.tv_sec++;
                } while (x.tv_usec >= MICROSECONDS);

        return x;
}
/* x = a - b */
static inline struct timeval
sub_tval(
        struct timeval  a,
        struct timeval  b
        )
{
        struct timeval  x;

        x = a;
        x.tv_sec -= b.tv_sec;
        x.tv_usec -= b.tv_usec;

        return normalize_tval(x);
}

/* x = abs(a) */
static inline struct timeval
abs_tval(
        struct timeval  a
        )
{
        struct timeval  c;

        c = normalize_tval(a);
        if (c.tv_sec < 0) {
                if (c.tv_usec != 0) {
                        c.tv_sec = -c.tv_sec - 1;
                        c.tv_usec = MICROSECONDS - c.tv_usec;
                } else {
                        c.tv_sec = -c.tv_sec;
                }
        }

        return c;
}

And the larger code fragment:


        /* get the current time as l_fp (without fuzz) and as struct timeval */
        get_ostime(&timets);
        fp_sys = tspec_stamp_to_lfp(timets);
        tvlast.tv_sec = timets.tv_sec;
        tvlast.tv_usec = (timets.tv_nsec + 500) / 1000;

        /* get the target time as l_fp */
        L_ADD(&fp_sys, &fp_ofs);

        /* unfold the new system time */
        timetv = lfp_stamp_to_tval(fp_sys, &pivot);

        /* now set new system time */
        if (ntp_set_tod(&timetv, NULL) != 0) {
                msyslog(LOG_ERR, "step-systime: %m");
                if (enable_panic_check && allow_panic) {
                        msyslog(LOG_ERR, "step_systime: allow_panic is TRUE!");
                }
                return FALSE;
        }

        /* <--- time-critical path ended with 'ntp_set_tod()' <--- */

        sys_residual = 0;
        lamport_violated = (step < 0);
        if (step_callback)
                (*step_callback)();

        tvdiff = abs_tval(sub_tval(timetv, tvlast));
        if (tvdiff.tv_sec != 0) {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]