Skip to content

Commit

Permalink
do not depend on signed integer overflow
Browse files Browse the repository at this point in the history
Signed integer overflow is not defined in C, so do not depend on it.

This fixes a problem with GCC 4.4.0 and -O3 where the optimizer would
consider "consumed_bytes > consumed_bytes + bytes" as a constant
expression, and never execute the die()-call.

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Acked-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Erik Faye-Lund authored and Junio C Hamano committed Oct 6, 2010
1 parent b90d9b8 commit c03c831
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 3 deletions.
2 changes: 1 addition & 1 deletion builtin/index-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ static void use(int bytes)
input_offset += bytes;

/* make sure off_t is sufficiently large not to wrap */
if (consumed_bytes > consumed_bytes + bytes)
if (signed_add_overflows(consumed_bytes, bytes))
die("pack too large for current definition of off_t");
consumed_bytes += bytes;
}
Expand Down
2 changes: 1 addition & 1 deletion builtin/pack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ static int write_one(struct sha1file *f,
written_list[nr_written++] = &e->idx;

/* make sure off_t is sufficiently large not to wrap */
if (*offset > *offset + size)
if (signed_add_overflows(*offset, size))
die("pack too large for current definition of off_t");
*offset += size;
return 1;
Expand Down
2 changes: 1 addition & 1 deletion builtin/unpack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ static void use(int bytes)
offset += bytes;

/* make sure off_t is sufficiently large not to wrap */
if (consumed_bytes > consumed_bytes + bytes)
if (signed_add_overflows(consumed_bytes, bytes))
die("pack too large for current definition of off_t");
consumed_bytes += bytes;
}
Expand Down
12 changes: 12 additions & 0 deletions git-compat-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#define bitsizeof(x) (CHAR_BIT * sizeof(x))

#define maximum_signed_value_of_type(a) \
(INTMAX_MAX >> (bitsizeof(intmax_t) - bitsizeof(a)))

/*
* Signed integer overflow is undefined in C, so here's a helper macro
* to detect if the sum of two integers will overflow.
*
* Requires: a >= 0, typeof(a) equals typeof(b)
*/
#define signed_add_overflows(a, b) \
((b) > maximum_signed_value_of_type(a) - (a))

#ifdef __GNUC__
#define TYPEOF(x) (__typeof__(x))
#else
Expand Down

0 comments on commit c03c831

Please sign in to comment.