summaryrefslogtreecommitdiff
path: root/src/lisp.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lisp.h')
-rw-r--r--src/lisp.h28
1 files changed, 26 insertions, 2 deletions
diff --git a/src/lisp.h b/src/lisp.h
index 5a07bda3592..79c96e11da8 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -35,6 +35,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#endif
#include <attribute.h>
+#include <count-leading-zeros.h>
#include <intprops.h>
#include <verify.h>
@@ -3909,6 +3910,20 @@ integer_to_uintmax (Lisp_Object num, uintmax_t *n)
}
}
+/* Return floor (log2 (N)) as an int, where 0 < N <= ULLONG_MAX. */
+#if (201112 <= __STDC_VERSION__ && INT_MAX <= UINT_MAX \
+ && LONG_MAX <= ULONG_MAX && LLONG_MAX <= ULLONG_MAX)
+# define elogb(n) \
+ _Generic (+(n), \
+ int: UINT_WIDTH - 1 - count_leading_zeros (n), \
+ unsigned int: UINT_WIDTH - 1 - count_leading_zeros (n), \
+ long: ULONG_WIDTH - 1 - count_leading_zeros_l (n), \
+ unsigned long: ULONG_WIDTH - 1 - count_leading_zeros_l (n), \
+ default: ULLONG_WIDTH - 1 - count_leading_zeros_ll (n))
+#else
+# define elogb(n) (ULLONG_WIDTH - 1 - count_leading_zeros_ll (n))
+#endif
+
/* A modification count. These are wide enough, and incremented
rarely enough, so that they should never overflow a 60-bit counter
in practice, and the code below assumes this so a compiler can
@@ -3918,11 +3933,12 @@ typedef intmax_t modiff_count;
INLINE modiff_count
modiff_incr (modiff_count *a, ptrdiff_t len)
{
- modiff_count a0 = *a; int incr = len ? 1 : 0;
+ modiff_count a0 = *a;
/* Increase the counter more for a large modification and less for a
small modification. Increase it logarithmically to avoid
increasing it too much. */
- while (len >>= 1) incr++;
+ verify (PTRDIFF_MAX <= ULLONG_MAX);
+ int incr = len == 0 ? 1 : elogb (len) + 1;
bool modiff_overflow = INT_ADD_WRAPV (a0, incr, a);
eassert (!modiff_overflow && *a >> 30 >> 30 == 0);
return a0;
@@ -5421,6 +5437,14 @@ safe_free_unbind_to (specpdl_ref count, specpdl_ref sa_count, Lisp_Object val)
return unbind_to (count, val);
}
+/* Work around GCC bug 109577
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109577
+ which causes GCC to mistakenly complain about the
+ memory allocation in SAFE_ALLOCA_LISP_EXTRA. */
+#if GNUC_PREREQ (13, 0, 0)
+# pragma GCC diagnostic ignored "-Wanalyzer-allocation-size"
+#endif
+
/* Set BUF to point to an allocated array of NELT Lisp_Objects,
immediately followed by EXTRA spare bytes. */