diff mbox series

[v2,5/7] git-compat-util: introduce more size_t helpers

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

Commit Message

Johannes Schindelin Oct. 28, 2021, 8:50 p.m. UTC
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(+)

Comments

Junio C Hamano Oct. 28, 2021, 11:05 p.m. UTC | #1
"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 mbox series

Patch

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))