osdep.h: Make TIME_MAX handle different time_t types

In our various supported host OSes, the time_t type may be either 32
or 64 bit, and could in theory also be either signed or unsigned.
Notably, in OpenBSD time_t is a 64 bit type even if 'long' is 32
bits, so using LONG_MAX for TIME_MAX is incorrect.

Use an approach suggested by Paolo Bonzini which calculates
the maximum value of the type rather than hardcoding it;
to do this we use the TYPE_MAXIMUM macro from Gnulib.

Backports commit e7b47c22e2df14d55e3e4426688c929bf8e3f7fb from qemu
This commit is contained in:
Peter Maydell 2018-03-05 12:27:11 -05:00 committed by Lioncash
parent c01b9a3cfe
commit 6285ed170e
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -127,8 +127,34 @@
#if !defined(EMEDIUMTYPE)
#define EMEDIUMTYPE 4098
#endif
/* time_t may be either 32 or 64 bits depending on the host OS, and
* can be either signed or unsigned, so we can't just hardcode a
* specific maximum value. This is not a C preprocessor constant,
* so you can't use TIME_MAX in an #ifdef, but for our purposes
* this isn't a problem.
*/
/* The macros TYPE_SIGNED, TYPE_WIDTH, and TYPE_MAXIMUM are from
* Gnulib, and are under the LGPL v2.1 or (at your option) any
* later version.
*/
/* True if the real type T is signed. */
#define TYPE_SIGNED(t) (!((t)0 < (t)-1))
/* The width in bits of the integer type or expression T.
* Padding bits are not supported.
*/
#define TYPE_WIDTH(t) (sizeof(t) * CHAR_BIT)
/* The maximum and minimum values for the integer type T. */
#define TYPE_MAXIMUM(t) \
((t) (!TYPE_SIGNED(t) \
? (t)-1 \
: ((((t)1 << (TYPE_WIDTH(t) - 2)) - 1) * 2 + 1)))
#ifndef TIME_MAX
#define TIME_MAX LONG_MAX
#define TIME_MAX TYPE_MAXIMUM(time_t)
#endif
/* HOST_LONG_BITS is the size of a native pointer in bits. */