Message ID | 32472ae3f98bbe0162b39a16109522ec18026404.1635454237.git.gitgitgadget@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Allow clean/smudge filters to handle huge files in the LLP64 data model | expand |
"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com> writes: > From: Johannes Schindelin <johannes.schindelin@gmx.de> > > We will use them in the next commit. > > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> > --- > git-compat-util.h | 25 +++++++++++++++++++++++++ > 1 file changed, 25 insertions(+) > > diff --git a/git-compat-util.h b/git-compat-util.h > index a508dbe5a35..7977720655c 100644 > --- a/git-compat-util.h > +++ b/git-compat-util.h > @@ -113,6 +113,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 types of "a" and "b" must be unsigned. The type of "a" must be unsigned, and there is no "b". "shift" can be of an integral type, and it probably is a good idea to feed a positive value that is smaller than bitsizeof(type(a)), but we probably do not have to say anything about it. > + * Note that this macro evaluates "a" twice! maximum_unsigned_value_of_type() does take bitsizeof() of the thing, but it only needs the type of it, not the value, so I doubt that it would evaluate 'a' even once. This macro does need the value of 'a' so it would evaluate it once. > + */ > +#define unsigned_left_shift_overflows(a, shift) \ > + ((a) > maximum_unsigned_value_of_type(a) >> shift) try: unsigned a = 0; int ov = unsigned_left_shift_overflows(++a, 4); printf("a = %d, ov = %d\n", a, ov); return 0; I think you'd get "a = 1".
diff --git a/git-compat-util.h b/git-compat-util.h index a508dbe5a35..7977720655c 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -113,6 +113,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 types of "a" and "b" must be unsigned. + * Note that this macro evaluates "a" twice! + */ +#define unsigned_left_shift_overflows(a, shift) \ + ((a) > maximum_unsigned_value_of_type(a) >> shift) + #ifdef __GNUC__ #define TYPEOF(x) (__typeof__(x)) #else @@ -859,6 +867,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))