diff options
Diffstat (limited to 'git-compat-util.h')
-rw-r--r-- | git-compat-util.h | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/git-compat-util.h b/git-compat-util.h index d70ce14286..b7caf23666 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -1,6 +1,19 @@ #ifndef GIT_COMPAT_UTIL_H #define GIT_COMPAT_UTIL_H +#if __STDC_VERSION__ - 0 < 199901L +/* + * Git is in a testing period for mandatory C99 support in the compiler. If + * your compiler is reasonably recent, you can try to enable C99 support (or, + * for MSVC, C11 support). If you encounter a problem and can't enable C99 + * support with your compiler (such as with "-std=gnu99") and don't have access + * to one with this support, such as GCC or Clang, you can remove this #if + * directive, but please report the details of your system to + * git@vger.kernel.org. + */ +#error "Required C99 support is in a test phase. Please see git-compat-util.h for more details." +#endif + #ifdef USE_MSVC_CRTDBG /* * For these to work they must appear very early in each @@ -33,14 +46,23 @@ /* * See if our compiler is known to support flexible array members. */ -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && (!defined(__SUNPRO_C) || (__SUNPRO_C > 0x580)) -# define FLEX_ARRAY /* empty */ + +/* + * Check vendor specific quirks first, before checking the + * __STDC_VERSION__, as vendor compilers can lie and we need to be + * able to work them around. Note that by not defining FLEX_ARRAY + * here, we can fall back to use the "safer but a bit wasteful" one + * later. + */ +#if defined(__SUNPRO_C) && (__SUNPRO_C <= 0x580) #elif defined(__GNUC__) # if (__GNUC__ >= 3) # define FLEX_ARRAY /* empty */ # else # define FLEX_ARRAY 0 /* older GNU extension */ # endif +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define FLEX_ARRAY /* empty */ #endif /* @@ -113,6 +135,14 @@ #define unsigned_mult_overflows(a, b) \ ((a) && (b) > maximum_unsigned_value_of_type(a) / (a)) +/* + * Returns true if the left shift of "a" by "shift" bits will + * overflow. The type of "a" must be unsigned. + */ +#define unsigned_left_shift_overflows(a, shift) \ + ((shift) < bitsizeof(a) && \ + (a) > maximum_unsigned_value_of_type(a) >> (shift)) + #ifdef __GNUC__ #define TYPEOF(x) (__typeof__(x)) #else @@ -127,7 +157,9 @@ /* Approximation of the length of the decimal representation of this type. */ #define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1) -#if defined(__sun__) +#ifdef __MINGW64__ +#define _POSIX_C_SOURCE 1 +#elif defined(__sun__) /* * On Solaris, when _XOPEN_EXTENDED is set, its header file * forces the programs to be XPG4v2, defeating any _XOPEN_SOURCE @@ -729,7 +761,7 @@ char *gitmkdtemp(char *); #ifdef NO_UNSETENV #define unsetenv gitunsetenv -void gitunsetenv(const char *); +int gitunsetenv(const char *); #endif #ifdef NO_STRCASESTR @@ -862,6 +894,23 @@ static inline size_t st_sub(size_t a, size_t b) return a - b; } +static inline size_t st_left_shift(size_t a, unsigned shift) +{ + if (unsigned_left_shift_overflows(a, shift)) + die("size_t overflow: %"PRIuMAX" << %u", + (uintmax_t)a, shift); + return a << shift; +} + +static inline unsigned long cast_size_t_to_ulong(size_t a) +{ + if (a != (unsigned long)a) + die("object too large to read on this platform: %" + PRIuMAX" is cut off to %lu", + (uintmax_t)a, (unsigned long)a); + return (unsigned long)a; +} + #ifdef HAVE_ALLOCA_H # include <alloca.h> # define xalloca(size) (alloca(size)) |