aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrea Corallo2020-08-09 15:03:23 +0200
committerAndrea Corallo2020-08-09 15:03:23 +0200
commit12a982d9789052d8e85efcacb4b311f4876c882a (patch)
treea452a8e888c6ee9c85d6a487359b7a1c0c9fa15b /src
parent80d7f710f2fab902e46aa3fddb8e1c1795420af3 (diff)
parent8e82baf5a730ff542118ddba5b76afdc1db643f6 (diff)
downloademacs-12a982d9789052d8e85efcacb4b311f4876c882a.tar.gz
emacs-12a982d9789052d8e85efcacb4b311f4876c882a.zip
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c52
-rw-r--r--src/buffer.c6
-rw-r--r--src/bytecode.c11
-rw-r--r--src/callint.c4
-rw-r--r--src/data.c6
-rw-r--r--src/dispnew.c7
-rw-r--r--src/editfns.c3
-rw-r--r--src/emacs-module.c8
-rw-r--r--src/emacs.c1
-rw-r--r--src/frame.c39
-rw-r--r--src/fringe.c5
-rw-r--r--src/gmalloc.c16
-rw-r--r--src/image.c20
-rw-r--r--src/lisp.h42
-rw-r--r--src/nsimage.m12
-rw-r--r--src/nsterm.h3
-rw-r--r--src/nsterm.m12
-rw-r--r--src/pdumper.c6
-rw-r--r--src/process.c97
-rw-r--r--src/ptr-bounds.h79
-rw-r--r--src/regex-emacs.c6
-rw-r--r--src/search.c6
-rw-r--r--src/xdisp.c54
-rw-r--r--src/xfns.c2
24 files changed, 179 insertions, 318 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 12f53bdd6d8..738a35ce715 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -34,7 +34,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
34#include "bignum.h" 34#include "bignum.h"
35#include "dispextern.h" 35#include "dispextern.h"
36#include "intervals.h" 36#include "intervals.h"
37#include "ptr-bounds.h"
38#include "puresize.h" 37#include "puresize.h"
39#include "sheap.h" 38#include "sheap.h"
40#include "sysstdio.h" 39#include "sysstdio.h"
@@ -1624,8 +1623,7 @@ static struct Lisp_String *string_free_list;
1624 a pointer to the `u.data' member of its sdata structure; the 1623 a pointer to the `u.data' member of its sdata structure; the
1625 structure starts at a constant offset in front of that. */ 1624 structure starts at a constant offset in front of that. */
1626 1625
1627#define SDATA_OF_STRING(S) ((sdata *) ptr_bounds_init ((S)->u.s.data \ 1626#define SDATA_OF_STRING(S) ((sdata *) ((S)->u.s.data - SDATA_DATA_OFFSET))
1628 - SDATA_DATA_OFFSET))
1629 1627
1630 1628
1631#ifdef GC_CHECK_STRING_OVERRUN 1629#ifdef GC_CHECK_STRING_OVERRUN
@@ -1799,7 +1797,7 @@ allocate_string (void)
1799 /* Every string on a free list should have NULL data pointer. */ 1797 /* Every string on a free list should have NULL data pointer. */
1800 s->u.s.data = NULL; 1798 s->u.s.data = NULL;
1801 NEXT_FREE_LISP_STRING (s) = string_free_list; 1799 NEXT_FREE_LISP_STRING (s) = string_free_list;
1802 string_free_list = ptr_bounds_clip (s, sizeof *s); 1800 string_free_list = s;
1803 } 1801 }
1804 } 1802 }
1805 1803
@@ -1908,7 +1906,7 @@ allocate_string_data (struct Lisp_String *s,
1908 1906
1909 MALLOC_UNBLOCK_INPUT; 1907 MALLOC_UNBLOCK_INPUT;
1910 1908
1911 s->u.s.data = ptr_bounds_clip (SDATA_DATA (data), nbytes + 1); 1909 s->u.s.data = SDATA_DATA (data);
1912#ifdef GC_CHECK_STRING_BYTES 1910#ifdef GC_CHECK_STRING_BYTES
1913 SDATA_NBYTES (data) = nbytes; 1911 SDATA_NBYTES (data) = nbytes;
1914#endif 1912#endif
@@ -2036,7 +2034,7 @@ sweep_strings (void)
2036 2034
2037 /* Put the string on the free-list. */ 2035 /* Put the string on the free-list. */
2038 NEXT_FREE_LISP_STRING (s) = string_free_list; 2036 NEXT_FREE_LISP_STRING (s) = string_free_list;
2039 string_free_list = ptr_bounds_clip (s, sizeof *s); 2037 string_free_list = s;
2040 ++nfree; 2038 ++nfree;
2041 } 2039 }
2042 } 2040 }
@@ -2044,7 +2042,7 @@ sweep_strings (void)
2044 { 2042 {
2045 /* S was on the free-list before. Put it there again. */ 2043 /* S was on the free-list before. Put it there again. */
2046 NEXT_FREE_LISP_STRING (s) = string_free_list; 2044 NEXT_FREE_LISP_STRING (s) = string_free_list;
2047 string_free_list = ptr_bounds_clip (s, sizeof *s); 2045 string_free_list = s;
2048 ++nfree; 2046 ++nfree;
2049 } 2047 }
2050 } 2048 }
@@ -2171,8 +2169,7 @@ compact_small_strings (void)
2171 { 2169 {
2172 eassert (tb != b || to < from); 2170 eassert (tb != b || to < from);
2173 memmove (to, from, size + GC_STRING_EXTRA); 2171 memmove (to, from, size + GC_STRING_EXTRA);
2174 to->string->u.s.data 2172 to->string->u.s.data = SDATA_DATA (to);
2175 = ptr_bounds_clip (SDATA_DATA (to), nbytes + 1);
2176 } 2173 }
2177 2174
2178 /* Advance past the sdata we copied to. */ 2175 /* Advance past the sdata we copied to. */
@@ -2959,7 +2956,6 @@ Lisp_Object zero_vector;
2959static void 2956static void
2960setup_on_free_list (struct Lisp_Vector *v, ptrdiff_t nbytes) 2957setup_on_free_list (struct Lisp_Vector *v, ptrdiff_t nbytes)
2961{ 2958{
2962 v = ptr_bounds_clip (v, nbytes);
2963 eassume (header_size <= nbytes); 2959 eassume (header_size <= nbytes);
2964 ptrdiff_t nwords = (nbytes - header_size) / word_size; 2960 ptrdiff_t nwords = (nbytes - header_size) / word_size;
2965 XSETPVECTYPESIZE (v, PVEC_FREE, 0, nwords); 2961 XSETPVECTYPESIZE (v, PVEC_FREE, 0, nwords);
@@ -3327,7 +3323,7 @@ allocate_vectorlike (ptrdiff_t len, bool clearit)
3327 3323
3328 MALLOC_UNBLOCK_INPUT; 3324 MALLOC_UNBLOCK_INPUT;
3329 3325
3330 return ptr_bounds_clip (p, nbytes); 3326 return p;
3331} 3327}
3332 3328
3333 3329
@@ -4481,7 +4477,6 @@ live_string_holding (struct mem_node *m, void *p)
4481 must not be on the free-list. */ 4477 must not be on the free-list. */
4482 if (0 <= offset && offset < sizeof b->strings) 4478 if (0 <= offset && offset < sizeof b->strings)
4483 { 4479 {
4484 cp = ptr_bounds_copy (cp, b);
4485 struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0]; 4480 struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0];
4486 if (s->u.s.data) 4481 if (s->u.s.data)
4487 return s; 4482 return s;
@@ -4514,7 +4509,6 @@ live_cons_holding (struct mem_node *m, void *p)
4514 && (b != cons_block 4509 && (b != cons_block
4515 || offset / sizeof b->conses[0] < cons_block_index)) 4510 || offset / sizeof b->conses[0] < cons_block_index))
4516 { 4511 {
4517 cp = ptr_bounds_copy (cp, b);
4518 struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0]; 4512 struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0];
4519 if (!deadp (s->u.s.car)) 4513 if (!deadp (s->u.s.car))
4520 return s; 4514 return s;
@@ -4548,7 +4542,6 @@ live_symbol_holding (struct mem_node *m, void *p)
4548 && (b != symbol_block 4542 && (b != symbol_block
4549 || offset / sizeof b->symbols[0] < symbol_block_index)) 4543 || offset / sizeof b->symbols[0] < symbol_block_index))
4550 { 4544 {
4551 cp = ptr_bounds_copy (cp, b);
4552 struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0]; 4545 struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0];
4553 if (!deadp (s->u.s.function)) 4546 if (!deadp (s->u.s.function))
4554 return s; 4547 return s;
@@ -4645,7 +4638,7 @@ mark_maybe_object (Lisp_Object obj)
4645#endif 4638#endif
4646 4639
4647 int type_tag = XTYPE (obj); 4640 int type_tag = XTYPE (obj);
4648 intptr_t offset; 4641 intptr_t pointer_word_tag = LISP_WORD_TAG (type_tag), offset, ipo;
4649 4642
4650 switch (type_tag) 4643 switch (type_tag)
4651 { 4644 {
@@ -4661,16 +4654,8 @@ mark_maybe_object (Lisp_Object obj)
4661 break; 4654 break;
4662 } 4655 }
4663 4656
4664 bool overflow 4657 INT_ADD_WRAPV ((intptr_t) XLP (obj), offset - pointer_word_tag, &ipo);
4665 = INT_SUBTRACT_WRAPV (offset, LISP_WORD_TAG (type_tag), &offset); 4658 void *po = (void *) ipo;
4666#if !defined WIDE_EMACS_INT || USE_LSB_TAG
4667 /* If we don't use wide integers, then `intptr_t' should always be
4668 large enough to not overflow. Furthermore, when using the least
4669 significant bits as tag bits, the tag is small enough to not
4670 overflow either. */
4671 eassert (!overflow);
4672#endif
4673 void *po = (char *) ((intptr_t) (char *) XLP (obj) + offset);
4674 4659
4675 /* If the pointer is in the dump image and the dump has a record 4660 /* If the pointer is in the dump image and the dump has a record
4676 of the object starting at the place where the pointer points, we 4661 of the object starting at the place where the pointer points, we
@@ -4873,7 +4858,7 @@ mark_memory (void const *start, void const *end)
4873 4858
4874 for (pp = start; (void const *) pp < end; pp += GC_POINTER_ALIGNMENT) 4859 for (pp = start; (void const *) pp < end; pp += GC_POINTER_ALIGNMENT)
4875 { 4860 {
4876 char *p = *(char *const *) pp; 4861 void *p = *(void *const *) pp;
4877 mark_maybe_pointer (p); 4862 mark_maybe_pointer (p);
4878 4863
4879 /* Unmask any struct Lisp_Symbol pointer that make_lisp_symbol 4864 /* Unmask any struct Lisp_Symbol pointer that make_lisp_symbol
@@ -4881,8 +4866,9 @@ mark_memory (void const *start, void const *end)
4881 On a host with 32-bit pointers and 64-bit Lisp_Objects, 4866 On a host with 32-bit pointers and 64-bit Lisp_Objects,
4882 a Lisp_Object might be split into registers saved into 4867 a Lisp_Object might be split into registers saved into
4883 non-adjacent words and P might be the low-order word's value. */ 4868 non-adjacent words and P might be the low-order word's value. */
4884 p = (char *) ((uintptr_t) p + (uintptr_t) lispsym); 4869 intptr_t ip;
4885 mark_maybe_pointer (p); 4870 INT_ADD_WRAPV ((intptr_t) p, (intptr_t) lispsym, &ip);
4871 mark_maybe_pointer ((void *) ip);
4886 4872
4887 verify (alignof (Lisp_Object) % GC_POINTER_ALIGNMENT == 0); 4873 verify (alignof (Lisp_Object) % GC_POINTER_ALIGNMENT == 0);
4888 if (alignof (Lisp_Object) == GC_POINTER_ALIGNMENT 4874 if (alignof (Lisp_Object) == GC_POINTER_ALIGNMENT
@@ -5261,7 +5247,7 @@ pure_alloc (size_t size, int type)
5261 pure_bytes_used = pure_bytes_used_lisp + pure_bytes_used_non_lisp; 5247 pure_bytes_used = pure_bytes_used_lisp + pure_bytes_used_non_lisp;
5262 5248
5263 if (pure_bytes_used <= pure_size) 5249 if (pure_bytes_used <= pure_size)
5264 return ptr_bounds_clip (result, size); 5250 return result;
5265 5251
5266 /* Don't allocate a large amount here, 5252 /* Don't allocate a large amount here,
5267 because it might get mmap'd and then its address 5253 because it might get mmap'd and then its address
@@ -5352,7 +5338,7 @@ find_string_data_in_pure (const char *data, ptrdiff_t nbytes)
5352 /* Check the remaining characters. */ 5338 /* Check the remaining characters. */
5353 if (memcmp (data, non_lisp_beg + start, nbytes) == 0) 5339 if (memcmp (data, non_lisp_beg + start, nbytes) == 0)
5354 /* Found. */ 5340 /* Found. */
5355 return ptr_bounds_clip (non_lisp_beg + start, nbytes + 1); 5341 return non_lisp_beg + start;
5356 5342
5357 start += last_char_skip; 5343 start += last_char_skip;
5358 } 5344 }
@@ -6076,7 +6062,6 @@ garbage_collect (void)
6076 stack_copy = xrealloc (stack_copy, stack_size); 6062 stack_copy = xrealloc (stack_copy, stack_size);
6077 stack_copy_size = stack_size; 6063 stack_copy_size = stack_size;
6078 } 6064 }
6079 stack = ptr_bounds_set (stack, stack_size);
6080 no_sanitize_memcpy (stack_copy, stack, stack_size); 6065 no_sanitize_memcpy (stack_copy, stack, stack_size);
6081 } 6066 }
6082 } 6067 }
@@ -6922,8 +6907,7 @@ sweep_conses (void)
6922 6907
6923 for (pos = start; pos < stop; pos++) 6908 for (pos = start; pos < stop; pos++)
6924 { 6909 {
6925 struct Lisp_Cons *acons 6910 struct Lisp_Cons *acons = &cblk->conses[pos];
6926 = ptr_bounds_copy (&cblk->conses[pos], cblk);
6927 if (!XCONS_MARKED_P (acons)) 6911 if (!XCONS_MARKED_P (acons))
6928 { 6912 {
6929 this_free++; 6913 this_free++;
@@ -6976,7 +6960,7 @@ sweep_floats (void)
6976 int this_free = 0; 6960 int this_free = 0;
6977 for (int i = 0; i < lim; i++) 6961 for (int i = 0; i < lim; i++)
6978 { 6962 {
6979 struct Lisp_Float *afloat = ptr_bounds_copy (&fblk->floats[i], fblk); 6963 struct Lisp_Float *afloat = &fblk->floats[i];
6980 if (!XFLOAT_MARKED_P (afloat)) 6964 if (!XFLOAT_MARKED_P (afloat))
6981 { 6965 {
6982 this_free++; 6966 this_free++;
diff --git a/src/buffer.c b/src/buffer.c
index e441499aeb0..241f2d43a93 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -28,10 +28,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
28#include <stdlib.h> 28#include <stdlib.h>
29#include <unistd.h> 29#include <unistd.h>
30 30
31#ifdef HAVE_SANITIZER_LSAN_INTERFACE_H
32#include <sanitizer/lsan_interface.h>
33#endif
34
35#include <verify.h> 31#include <verify.h>
36 32
37#include "lisp.h" 33#include "lisp.h"
@@ -5087,9 +5083,7 @@ enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
5087#else 5083#else
5088 p = xrealloc (b->text->beg, new_nbytes); 5084 p = xrealloc (b->text->beg, new_nbytes);
5089#endif 5085#endif
5090#ifdef HAVE___LSAN_IGNORE_OBJECT
5091 __lsan_ignore_object (p); 5086 __lsan_ignore_object (p);
5092#endif
5093 5087
5094 if (p == NULL) 5088 if (p == NULL)
5095 { 5089 {
diff --git a/src/bytecode.c b/src/bytecode.c
index 5ac30aa1010..1913a4812a0 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -24,7 +24,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
24#include "character.h" 24#include "character.h"
25#include "buffer.h" 25#include "buffer.h"
26#include "keyboard.h" 26#include "keyboard.h"
27#include "ptr-bounds.h"
28#include "syntax.h" 27#include "syntax.h"
29#include "window.h" 28#include "window.h"
30 29
@@ -47,7 +46,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
47 indirect threaded, using GCC's computed goto extension. This code, 46 indirect threaded, using GCC's computed goto extension. This code,
48 as currently implemented, is incompatible with BYTE_CODE_SAFE and 47 as currently implemented, is incompatible with BYTE_CODE_SAFE and
49 BYTE_CODE_METER. */ 48 BYTE_CODE_METER. */
50#if (defined __GNUC__ && !defined __STRICT_ANSI__ && !defined __CHKP__ \ 49#if (defined __GNUC__ && !defined __STRICT_ANSI__ \
51 && !BYTE_CODE_SAFE && !defined BYTE_CODE_METER) 50 && !BYTE_CODE_SAFE && !defined BYTE_CODE_METER)
52#define BYTE_CODE_THREADED 51#define BYTE_CODE_THREADED
53#endif 52#endif
@@ -368,14 +367,12 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
368 USE_SAFE_ALLOCA; 367 USE_SAFE_ALLOCA;
369 void *alloc; 368 void *alloc;
370 SAFE_ALLOCA_LISP_EXTRA (alloc, stack_items, bytestr_length); 369 SAFE_ALLOCA_LISP_EXTRA (alloc, stack_items, bytestr_length);
371 ptrdiff_t item_bytes = stack_items * word_size; 370 Lisp_Object *stack_base = alloc;
372 Lisp_Object *stack_base = ptr_bounds_clip (alloc, item_bytes);
373 Lisp_Object *top = stack_base; 371 Lisp_Object *top = stack_base;
374 *top = vector; /* Ensure VECTOR survives GC (Bug#33014). */ 372 *top = vector; /* Ensure VECTOR survives GC (Bug#33014). */
375 Lisp_Object *stack_lim = stack_base + stack_items; 373 Lisp_Object *stack_lim = stack_base + stack_items;
376 unsigned char *bytestr_data = alloc; 374 unsigned char const *bytestr_data = memcpy (stack_lim,
377 bytestr_data = ptr_bounds_clip (bytestr_data + item_bytes, bytestr_length); 375 SDATA (bytestr), bytestr_length);
378 memcpy (bytestr_data, SDATA (bytestr), bytestr_length);
379 unsigned char const *pc = bytestr_data; 376 unsigned char const *pc = bytestr_data;
380 ptrdiff_t count = SPECPDL_INDEX (); 377 ptrdiff_t count = SPECPDL_INDEX ();
381 378
diff --git a/src/callint.c b/src/callint.c
index eb916353a0c..f609c96a6fa 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -21,7 +21,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
21#include <config.h> 21#include <config.h>
22 22
23#include "lisp.h" 23#include "lisp.h"
24#include "ptr-bounds.h"
25#include "character.h" 24#include "character.h"
26#include "buffer.h" 25#include "buffer.h"
27#include "keyboard.h" 26#include "keyboard.h"
@@ -440,9 +439,6 @@ invoke it (via an `interactive' spec that contains, for instance, an
440 signed char *varies = (signed char *) (visargs + nargs); 439 signed char *varies = (signed char *) (visargs + nargs);
441 440
442 memclear (args, nargs * (2 * word_size + 1)); 441 memclear (args, nargs * (2 * word_size + 1));
443 args = ptr_bounds_clip (args, nargs * sizeof *args);
444 visargs = ptr_bounds_clip (visargs, nargs * sizeof *visargs);
445 varies = ptr_bounds_clip (varies, nargs * sizeof *varies);
446 442
447 if (!NILP (enable)) 443 if (!NILP (enable))
448 specbind (Qenable_recursive_minibuffers, Qt); 444 specbind (Qenable_recursive_minibuffers, Qt);
diff --git a/src/data.c b/src/data.c
index e827695d295..33711368f13 100644
--- a/src/data.c
+++ b/src/data.c
@@ -23,10 +23,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
23#include <math.h> 23#include <math.h>
24#include <stdio.h> 24#include <stdio.h>
25 25
26#ifdef HAVE_SANITIZER_LSAN_INTERFACE_H
27#include <sanitizer/lsan_interface.h>
28#endif
29
30#include <byteswap.h> 26#include <byteswap.h>
31#include <count-one-bits.h> 27#include <count-one-bits.h>
32#include <count-trailing-zeros.h> 28#include <count-trailing-zeros.h>
@@ -1834,9 +1830,7 @@ make_blv (struct Lisp_Symbol *sym, bool forwarded,
1834 set_blv_defcell (blv, tem); 1830 set_blv_defcell (blv, tem);
1835 set_blv_valcell (blv, tem); 1831 set_blv_valcell (blv, tem);
1836 set_blv_found (blv, false); 1832 set_blv_found (blv, false);
1837#ifdef HAVE___LSAN_IGNORE_OBJECT
1838 __lsan_ignore_object (blv); 1833 __lsan_ignore_object (blv);
1839#endif
1840 return blv; 1834 return blv;
1841} 1835}
1842 1836
diff --git a/src/dispnew.c b/src/dispnew.c
index 1ae59e3ff2b..d318e26308e 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -25,7 +25,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
25#include <unistd.h> 25#include <unistd.h>
26 26
27#include "lisp.h" 27#include "lisp.h"
28#include "ptr-bounds.h"
29#include "termchar.h" 28#include "termchar.h"
30/* cm.h must come after dispextern.h on Windows. */ 29/* cm.h must come after dispextern.h on Windows. */
31#include "dispextern.h" 30#include "dispextern.h"
@@ -4891,12 +4890,6 @@ scrolling (struct frame *frame)
4891 unsigned *new_hash = old_hash + height; 4890 unsigned *new_hash = old_hash + height;
4892 int *draw_cost = (int *) (new_hash + height); 4891 int *draw_cost = (int *) (new_hash + height);
4893 int *old_draw_cost = draw_cost + height; 4892 int *old_draw_cost = draw_cost + height;
4894 old_hash = ptr_bounds_clip (old_hash, height * sizeof *old_hash);
4895 new_hash = ptr_bounds_clip (new_hash, height * sizeof *new_hash);
4896 draw_cost = ptr_bounds_clip (draw_cost, height * sizeof *draw_cost);
4897 old_draw_cost = ptr_bounds_clip (old_draw_cost,
4898 height * sizeof *old_draw_cost);
4899
4900 eassert (current_matrix); 4893 eassert (current_matrix);
4901 4894
4902 /* Compute hash codes of all the lines. Also calculate number of 4895 /* Compute hash codes of all the lines. Also calculate number of
diff --git a/src/editfns.c b/src/editfns.c
index 763d95bb8fa..cb09ea8a31a 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -46,7 +46,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
46 46
47#include "composite.h" 47#include "composite.h"
48#include "intervals.h" 48#include "intervals.h"
49#include "ptr-bounds.h"
50#include "systime.h" 49#include "systime.h"
51#include "character.h" 50#include "character.h"
52#include "buffer.h" 51#include "buffer.h"
@@ -3131,8 +3130,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
3131 string was not copied into the output. 3130 string was not copied into the output.
3132 It is 2 if byte I was not the first byte of its character. */ 3131 It is 2 if byte I was not the first byte of its character. */
3133 char *discarded = (char *) &info[nspec_bound]; 3132 char *discarded = (char *) &info[nspec_bound];
3134 info = ptr_bounds_clip (info, info_size);
3135 discarded = ptr_bounds_clip (discarded, formatlen);
3136 memset (discarded, 0, formatlen); 3133 memset (discarded, 0, formatlen);
3137 3134
3138 /* Try to determine whether the result should be multibyte. 3135 /* Try to determine whether the result should be multibyte.
diff --git a/src/emacs-module.c b/src/emacs-module.c
index f57101946b3..a0bab118019 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -84,10 +84,6 @@ To add a new module function, proceed as follows:
84#include <stdlib.h> 84#include <stdlib.h>
85#include <time.h> 85#include <time.h>
86 86
87#ifdef HAVE_SANITIZER_LSAN_INTERFACE_H
88#include <sanitizer/lsan_interface.h>
89#endif
90
91#include "lisp.h" 87#include "lisp.h"
92#include "bignum.h" 88#include "bignum.h"
93#include "dynlib.h" 89#include "dynlib.h"
@@ -1103,9 +1099,7 @@ DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0,
1103 if (module_assertions) 1099 if (module_assertions)
1104 { 1100 {
1105 rt = xmalloc (sizeof *rt); 1101 rt = xmalloc (sizeof *rt);
1106#ifdef HAVE___LSAN_IGNORE_OBJECT
1107 __lsan_ignore_object (rt); 1102 __lsan_ignore_object (rt);
1108#endif
1109 } 1103 }
1110 else 1104 else
1111 rt = &rt_pub; 1105 rt = &rt_pub;
@@ -1426,9 +1420,7 @@ initialize_environment (emacs_env *env, struct emacs_env_private *priv)
1426 if (module_assertions) 1420 if (module_assertions)
1427 { 1421 {
1428 env = xmalloc (sizeof *env); 1422 env = xmalloc (sizeof *env);
1429#ifdef HAVE___LSAN_IGNORE_OBJECT
1430 __lsan_ignore_object (env); 1423 __lsan_ignore_object (env);
1431#endif
1432 } 1424 }
1433 1425
1434 priv->pending_non_local_exit = emacs_funcall_exit_return; 1426 priv->pending_non_local_exit = emacs_funcall_exit_return;
diff --git a/src/emacs.c b/src/emacs.c
index 34717cdae2f..8c252276352 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -83,7 +83,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
83#include "charset.h" 83#include "charset.h"
84#include "composite.h" 84#include "composite.h"
85#include "dispextern.h" 85#include "dispextern.h"
86#include "ptr-bounds.h"
87#include "regex-emacs.h" 86#include "regex-emacs.h"
88#include "sheap.h" 87#include "sheap.h"
89#include "syntax.h" 88#include "syntax.h"
diff --git a/src/frame.c b/src/frame.c
index c871e4fd994..c4dfc35a0c5 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -35,7 +35,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
35#include "buffer.h" 35#include "buffer.h"
36/* These help us bind and responding to switch-frame events. */ 36/* These help us bind and responding to switch-frame events. */
37#include "keyboard.h" 37#include "keyboard.h"
38#include "ptr-bounds.h"
39#include "frame.h" 38#include "frame.h"
40#include "blockinput.h" 39#include "blockinput.h"
41#include "termchar.h" 40#include "termchar.h"
@@ -2566,21 +2565,18 @@ before calling this function on it, like this.
2566 if (FRAME_WINDOW_P (XFRAME (frame))) 2565 if (FRAME_WINDOW_P (XFRAME (frame)))
2567 /* Warping the mouse will cause enternotify and focus events. */ 2566 /* Warping the mouse will cause enternotify and focus events. */
2568 frame_set_mouse_position (XFRAME (frame), xval, yval); 2567 frame_set_mouse_position (XFRAME (frame), xval, yval);
2569#else 2568#elif defined MSDOS
2570#if defined (MSDOS)
2571 if (FRAME_MSDOS_P (XFRAME (frame))) 2569 if (FRAME_MSDOS_P (XFRAME (frame)))
2572 { 2570 {
2573 Fselect_frame (frame, Qnil); 2571 Fselect_frame (frame, Qnil);
2574 mouse_moveto (xval, yval); 2572 mouse_moveto (xval, yval);
2575 } 2573 }
2574#elif defined HAVE_GPM
2575 Fselect_frame (frame, Qnil);
2576 term_mouse_moveto (xval, yval);
2576#else 2577#else
2577#ifdef HAVE_GPM 2578 (void) xval;
2578 { 2579 (void) yval;
2579 Fselect_frame (frame, Qnil);
2580 term_mouse_moveto (xval, yval);
2581 }
2582#endif
2583#endif
2584#endif 2580#endif
2585 2581
2586 return Qnil; 2582 return Qnil;
@@ -2607,21 +2603,18 @@ before calling this function on it, like this.
2607 if (FRAME_WINDOW_P (XFRAME (frame))) 2603 if (FRAME_WINDOW_P (XFRAME (frame)))
2608 /* Warping the mouse will cause enternotify and focus events. */ 2604 /* Warping the mouse will cause enternotify and focus events. */
2609 frame_set_mouse_pixel_position (XFRAME (frame), xval, yval); 2605 frame_set_mouse_pixel_position (XFRAME (frame), xval, yval);
2610#else 2606#elif defined MSDOS
2611#if defined (MSDOS)
2612 if (FRAME_MSDOS_P (XFRAME (frame))) 2607 if (FRAME_MSDOS_P (XFRAME (frame)))
2613 { 2608 {
2614 Fselect_frame (frame, Qnil); 2609 Fselect_frame (frame, Qnil);
2615 mouse_moveto (xval, yval); 2610 mouse_moveto (xval, yval);
2616 } 2611 }
2612#elif defined HAVE_GPM
2613 Fselect_frame (frame, Qnil);
2614 term_mouse_moveto (xval, yval);
2617#else 2615#else
2618#ifdef HAVE_GPM 2616 (void) xval;
2619 { 2617 (void) yval;
2620 Fselect_frame (frame, Qnil);
2621 term_mouse_moveto (xval, yval);
2622 }
2623#endif
2624#endif
2625#endif 2618#endif
2626 2619
2627 return Qnil; 2620 return Qnil;
@@ -3658,6 +3651,9 @@ bottom edge of FRAME's display. */)
3658#ifdef HAVE_WINDOW_SYSTEM 3651#ifdef HAVE_WINDOW_SYSTEM
3659 if (FRAME_TERMINAL (f)->set_frame_offset_hook) 3652 if (FRAME_TERMINAL (f)->set_frame_offset_hook)
3660 FRAME_TERMINAL (f)->set_frame_offset_hook (f, xval, yval, 1); 3653 FRAME_TERMINAL (f)->set_frame_offset_hook (f, xval, yval, 1);
3654#else
3655 (void) xval;
3656 (void) yval;
3661#endif 3657#endif
3662 } 3658 }
3663 3659
@@ -5019,8 +5015,6 @@ gui_display_get_resource (Display_Info *dpyinfo, Lisp_Object attribute,
5019 USE_SAFE_ALLOCA; 5015 USE_SAFE_ALLOCA;
5020 char *name_key = SAFE_ALLOCA (name_keysize + class_keysize); 5016 char *name_key = SAFE_ALLOCA (name_keysize + class_keysize);
5021 char *class_key = name_key + name_keysize; 5017 char *class_key = name_key + name_keysize;
5022 name_key = ptr_bounds_clip (name_key, name_keysize);
5023 class_key = ptr_bounds_clip (class_key, class_keysize);
5024 5018
5025 /* Start with emacs.FRAMENAME for the name (the specific one) 5019 /* Start with emacs.FRAMENAME for the name (the specific one)
5026 and with `Emacs' for the class key (the general one). */ 5020 and with `Emacs' for the class key (the general one). */
@@ -5091,9 +5085,6 @@ x_get_resource_string (const char *attribute, const char *class)
5091 ptrdiff_t class_keysize = sizeof (EMACS_CLASS) - 1 + strlen (class) + 2; 5085 ptrdiff_t class_keysize = sizeof (EMACS_CLASS) - 1 + strlen (class) + 2;
5092 char *name_key = SAFE_ALLOCA (name_keysize + class_keysize); 5086 char *name_key = SAFE_ALLOCA (name_keysize + class_keysize);
5093 char *class_key = name_key + name_keysize; 5087 char *class_key = name_key + name_keysize;
5094 name_key = ptr_bounds_clip (name_key, name_keysize);
5095 class_key = ptr_bounds_clip (class_key, class_keysize);
5096
5097 esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute); 5088 esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute);
5098 sprintf (class_key, "%s.%s", EMACS_CLASS, class); 5089 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
5099 5090
diff --git a/src/fringe.c b/src/fringe.c
index fc4c738dc2d..c3d64fefc82 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -23,7 +23,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
23 23
24#include "lisp.h" 24#include "lisp.h"
25#include "frame.h" 25#include "frame.h"
26#include "ptr-bounds.h"
27#include "window.h" 26#include "window.h"
28#include "dispextern.h" 27#include "dispextern.h"
29#include "buffer.h" 28#include "buffer.h"
@@ -1607,9 +1606,7 @@ If BITMAP already exists, the existing definition is replaced. */)
1607 fb.dynamic = true; 1606 fb.dynamic = true;
1608 1607
1609 xfb = xmalloc (sizeof fb + fb.height * BYTES_PER_BITMAP_ROW); 1608 xfb = xmalloc (sizeof fb + fb.height * BYTES_PER_BITMAP_ROW);
1610 fb.bits = b = ((unsigned short *) 1609 fb.bits = b = (unsigned short *) (xfb + 1);
1611 ptr_bounds_clip (xfb + 1, fb.height * BYTES_PER_BITMAP_ROW));
1612 xfb = ptr_bounds_clip (xfb, sizeof *xfb);
1613 1610
1614 j = 0; 1611 j = 0;
1615 while (j < fb.height) 1612 while (j < fb.height)
diff --git a/src/gmalloc.c b/src/gmalloc.c
index 8450a639e77..3560c744539 100644
--- a/src/gmalloc.c
+++ b/src/gmalloc.c
@@ -38,8 +38,6 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>.
38 38
39#include "lisp.h" 39#include "lisp.h"
40 40
41#include "ptr-bounds.h"
42
43#ifdef HAVE_MALLOC_H 41#ifdef HAVE_MALLOC_H
44# if GNUC_PREREQ (4, 2, 0) 42# if GNUC_PREREQ (4, 2, 0)
45# pragma GCC diagnostic ignored "-Wdeprecated-declarations" 43# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@@ -200,8 +198,7 @@ extern size_t _bytes_free;
200 198
201/* Internal versions of `malloc', `realloc', and `free' 199/* Internal versions of `malloc', `realloc', and `free'
202 used when these functions need to call each other. 200 used when these functions need to call each other.
203 They are the same but don't call the hooks 201 They are the same but don't call the hooks. */
204 and don't bound the resulting pointers. */
205extern void *_malloc_internal (size_t); 202extern void *_malloc_internal (size_t);
206extern void *_realloc_internal (void *, size_t); 203extern void *_realloc_internal (void *, size_t);
207extern void _free_internal (void *); 204extern void _free_internal (void *);
@@ -551,7 +548,7 @@ malloc_initialize_1 (void)
551 _heapinfo[0].free.size = 0; 548 _heapinfo[0].free.size = 0;
552 _heapinfo[0].free.next = _heapinfo[0].free.prev = 0; 549 _heapinfo[0].free.next = _heapinfo[0].free.prev = 0;
553 _heapindex = 0; 550 _heapindex = 0;
554 _heapbase = (char *) ptr_bounds_init (_heapinfo); 551 _heapbase = (char *) _heapinfo;
555 _heaplimit = BLOCK (_heapbase + heapsize * sizeof (malloc_info)); 552 _heaplimit = BLOCK (_heapbase + heapsize * sizeof (malloc_info));
556 553
557 register_heapinfo (); 554 register_heapinfo ();
@@ -912,8 +909,7 @@ malloc (size_t size)
912 among multiple threads. We just leave it for compatibility with 909 among multiple threads. We just leave it for compatibility with
913 glibc malloc (i.e., assignments to gmalloc_hook) for now. */ 910 glibc malloc (i.e., assignments to gmalloc_hook) for now. */
914 hook = gmalloc_hook; 911 hook = gmalloc_hook;
915 void *result = (hook ? hook : _malloc_internal) (size); 912 return (hook ? hook : _malloc_internal) (size);
916 return ptr_bounds_clip (result, size);
917} 913}
918 914
919#if !(defined (_LIBC) || defined (HYBRID_MALLOC)) 915#if !(defined (_LIBC) || defined (HYBRID_MALLOC))
@@ -991,7 +987,6 @@ _free_internal_nolock (void *ptr)
991 987
992 if (ptr == NULL) 988 if (ptr == NULL)
993 return; 989 return;
994 ptr = ptr_bounds_init (ptr);
995 990
996 PROTECT_MALLOC_STATE (0); 991 PROTECT_MALLOC_STATE (0);
997 992
@@ -1303,7 +1298,6 @@ _realloc_internal_nolock (void *ptr, size_t size)
1303 else if (ptr == NULL) 1298 else if (ptr == NULL)
1304 return _malloc_internal_nolock (size); 1299 return _malloc_internal_nolock (size);
1305 1300
1306 ptr = ptr_bounds_init (ptr);
1307 block = BLOCK (ptr); 1301 block = BLOCK (ptr);
1308 1302
1309 PROTECT_MALLOC_STATE (0); 1303 PROTECT_MALLOC_STATE (0);
@@ -1426,8 +1420,7 @@ realloc (void *ptr, size_t size)
1426 return NULL; 1420 return NULL;
1427 1421
1428 hook = grealloc_hook; 1422 hook = grealloc_hook;
1429 void *result = (hook ? hook : _realloc_internal) (ptr, size); 1423 return (hook ? hook : _realloc_internal) (ptr, size);
1430 return ptr_bounds_clip (result, size);
1431} 1424}
1432/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. 1425/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
1433 1426
@@ -1601,7 +1594,6 @@ aligned_alloc (size_t alignment, size_t size)
1601 { 1594 {
1602 l->exact = result; 1595 l->exact = result;
1603 result = l->aligned = (char *) result + adj; 1596 result = l->aligned = (char *) result + adj;
1604 result = ptr_bounds_clip (result, size);
1605 } 1597 }
1606 UNLOCK_ALIGNED_BLOCKS (); 1598 UNLOCK_ALIGNED_BLOCKS ();
1607 if (l == NULL) 1599 if (l == NULL)
diff --git a/src/image.c b/src/image.c
index e7e0a93313b..e236b389210 100644
--- a/src/image.c
+++ b/src/image.c
@@ -259,6 +259,8 @@ cr_put_image_to_cr_data (struct image *img)
259 cairo_matrix_t matrix; 259 cairo_matrix_t matrix;
260 cairo_pattern_get_matrix (img->cr_data, &matrix); 260 cairo_pattern_get_matrix (img->cr_data, &matrix);
261 cairo_pattern_set_matrix (pattern, &matrix); 261 cairo_pattern_set_matrix (pattern, &matrix);
262 cairo_pattern_set_filter
263 (pattern, cairo_pattern_get_filter (img->cr_data));
262 cairo_pattern_destroy (img->cr_data); 264 cairo_pattern_destroy (img->cr_data);
263 } 265 }
264 cairo_surface_destroy (surface); 266 cairo_surface_destroy (surface);
@@ -2114,6 +2116,15 @@ image_set_transform (struct frame *f, struct image *img)
2114 double rotation = 0.0; 2116 double rotation = 0.0;
2115 compute_image_rotation (img, &rotation); 2117 compute_image_rotation (img, &rotation);
2116 2118
2119# if defined USE_CAIRO || defined HAVE_XRENDER || defined HAVE_NS
2120 /* We want scale up operations to use a nearest neighbour filter to
2121 show real pixels instead of munging them, but scale down
2122 operations to use a blended filter, to avoid aliasing and the like.
2123
2124 TODO: implement for Windows. */
2125 bool scale_down = (width < img->width) || (height < img->height);
2126# endif
2127
2117 /* Perform scale transformation. */ 2128 /* Perform scale transformation. */
2118 2129
2119 matrix3x3 matrix 2130 matrix3x3 matrix
@@ -2225,11 +2236,14 @@ image_set_transform (struct frame *f, struct image *img)
2225 /* Under NS the transform is applied to the drawing surface at 2236 /* Under NS the transform is applied to the drawing surface at
2226 drawing time, so store it for later. */ 2237 drawing time, so store it for later. */
2227 ns_image_set_transform (img->pixmap, matrix); 2238 ns_image_set_transform (img->pixmap, matrix);
2239 ns_image_set_smoothing (img->pixmap, scale_down);
2228# elif defined USE_CAIRO 2240# elif defined USE_CAIRO
2229 cairo_matrix_t cr_matrix = {matrix[0][0], matrix[0][1], matrix[1][0], 2241 cairo_matrix_t cr_matrix = {matrix[0][0], matrix[0][1], matrix[1][0],
2230 matrix[1][1], matrix[2][0], matrix[2][1]}; 2242 matrix[1][1], matrix[2][0], matrix[2][1]};
2231 cairo_pattern_t *pattern = cairo_pattern_create_rgb (0, 0, 0); 2243 cairo_pattern_t *pattern = cairo_pattern_create_rgb (0, 0, 0);
2232 cairo_pattern_set_matrix (pattern, &cr_matrix); 2244 cairo_pattern_set_matrix (pattern, &cr_matrix);
2245 cairo_pattern_set_filter (pattern, scale_down
2246 ? CAIRO_FILTER_BEST : CAIRO_FILTER_NEAREST);
2233 /* Dummy solid color pattern just to record pattern matrix. */ 2247 /* Dummy solid color pattern just to record pattern matrix. */
2234 img->cr_data = pattern; 2248 img->cr_data = pattern;
2235# elif defined (HAVE_XRENDER) 2249# elif defined (HAVE_XRENDER)
@@ -2246,14 +2260,14 @@ image_set_transform (struct frame *f, struct image *img)
2246 XDoubleToFixed (matrix[1][2]), 2260 XDoubleToFixed (matrix[1][2]),
2247 XDoubleToFixed (matrix[2][2])}}}; 2261 XDoubleToFixed (matrix[2][2])}}};
2248 2262
2249 XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->picture, FilterBest, 2263 XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->picture,
2250 0, 0); 2264 scale_down ? FilterBest : FilterNearest, 0, 0);
2251 XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->picture, &tmat); 2265 XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->picture, &tmat);
2252 2266
2253 if (img->mask_picture) 2267 if (img->mask_picture)
2254 { 2268 {
2255 XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->mask_picture, 2269 XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->mask_picture,
2256 FilterBest, 0, 0); 2270 scale_down ? FilterBest : FilterNearest, 0, 0);
2257 XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->mask_picture, 2271 XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->mask_picture,
2258 &tmat); 2272 &tmat);
2259 } 2273 }
diff --git a/src/lisp.h b/src/lisp.h
index 5ef31eff31e..75ef6d30f97 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -894,8 +894,8 @@ verify (GCALIGNED (struct Lisp_Symbol));
894 convert it to a Lisp_Word. */ 894 convert it to a Lisp_Word. */
895#if LISP_WORDS_ARE_POINTERS 895#if LISP_WORDS_ARE_POINTERS
896/* untagged_ptr is a pointer so that the compiler knows that TAG_PTR 896/* untagged_ptr is a pointer so that the compiler knows that TAG_PTR
897 yields a pointer; this can help with gcc -fcheck-pointer-bounds. 897 yields a pointer. It is char * so that adding a tag uses simple
898 It is char * so that adding a tag uses simple machine addition. */ 898 machine addition. */
899typedef char *untagged_ptr; 899typedef char *untagged_ptr;
900typedef uintptr_t Lisp_Word_tag; 900typedef uintptr_t Lisp_Word_tag;
901#else 901#else
@@ -923,13 +923,9 @@ typedef EMACS_UINT Lisp_Word_tag;
923 when using a debugger like GDB, on older platforms where the debug 923 when using a debugger like GDB, on older platforms where the debug
924 format does not represent C macros. However, they are unbounded 924 format does not represent C macros. However, they are unbounded
925 and would just be asking for trouble if checking pointer bounds. */ 925 and would just be asking for trouble if checking pointer bounds. */
926#ifdef __CHKP__ 926#define DEFINE_LISP_SYMBOL(name) \
927# define DEFINE_LISP_SYMBOL(name) 927 DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
928#else 928 DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
929# define DEFINE_LISP_SYMBOL(name) \
930 DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
931 DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
932#endif
933 929
934/* The index of the C-defined Lisp symbol SYM. 930/* The index of the C-defined Lisp symbol SYM.
935 This can be used in a static initializer. */ 931 This can be used in a static initializer. */
@@ -1003,30 +999,15 @@ XSYMBOL (Lisp_Object a)
1003 eassert (SYMBOLP (a)); 999 eassert (SYMBOLP (a));
1004 intptr_t i = (intptr_t) XUNTAG (a, Lisp_Symbol, struct Lisp_Symbol); 1000 intptr_t i = (intptr_t) XUNTAG (a, Lisp_Symbol, struct Lisp_Symbol);
1005 void *p = (char *) lispsym + i; 1001 void *p = (char *) lispsym + i;
1006#ifdef __CHKP__
1007 /* Bypass pointer checking. Although this could be improved it is
1008 probably not worth the trouble. */
1009 p = __builtin___bnd_set_ptr_bounds (p, sizeof (struct Lisp_Symbol));
1010#endif
1011 return p; 1002 return p;
1012} 1003}
1013 1004
1014INLINE Lisp_Object 1005INLINE Lisp_Object
1015make_lisp_symbol (struct Lisp_Symbol *sym) 1006make_lisp_symbol (struct Lisp_Symbol *sym)
1016{ 1007{
1017#ifdef __CHKP__ 1008 /* GCC 7 x86-64 generates faster code if lispsym is
1018 /* Although '__builtin___bnd_narrow_ptr_bounds (sym, sym, sizeof *sym)'
1019 should be more efficient, it runs afoul of GCC bug 83251
1020 <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83251>.
1021 Also, attempting to call __builtin___bnd_chk_ptr_bounds (sym, sizeof *sym)
1022 here seems to trigger a GCC bug, as yet undiagnosed. */
1023 char *addr = __builtin___bnd_set_ptr_bounds (sym, sizeof *sym);
1024 char *symoffset = addr - (intptr_t) lispsym;
1025#else
1026 /* If !__CHKP__, GCC 7 x86-64 generates faster code if lispsym is
1027 cast to char * rather than to intptr_t. */ 1009 cast to char * rather than to intptr_t. */
1028 char *symoffset = (char *) ((char *) sym - (char *) lispsym); 1010 char *symoffset = (char *) ((char *) sym - (char *) lispsym);
1029#endif
1030 Lisp_Object a = TAG_PTR (Lisp_Symbol, symoffset); 1011 Lisp_Object a = TAG_PTR (Lisp_Symbol, symoffset);
1031 eassert (XSYMBOL (a) == sym); 1012 eassert (XSYMBOL (a) == sym);
1032 return a; 1013 return a;
@@ -4837,6 +4818,17 @@ lispstpcpy (char *dest, Lisp_Object string)
4837 return dest + len; 4818 return dest + len;
4838} 4819}
4839 4820
4821#if (defined HAVE___LSAN_IGNORE_OBJECT \
4822 && defined HAVE_SANITIZER_LSAN_INTERFACE_H)
4823# include <sanitizer/lsan_interface.h>
4824#else
4825/* Treat *P as a non-leak. */
4826INLINE void
4827__lsan_ignore_object (void const *p)
4828{
4829}
4830#endif
4831
4840extern void xputenv (const char *); 4832extern void xputenv (const char *);
4841 4833
4842extern char *egetenv_internal (const char *, ptrdiff_t); 4834extern char *egetenv_internal (const char *, ptrdiff_t);
diff --git a/src/nsimage.m b/src/nsimage.m
index 07750de95fe..966e7044f12 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -199,6 +199,12 @@ ns_image_set_transform (void *img, double m[3][3])
199 [(EmacsImage *)img setTransform:m]; 199 [(EmacsImage *)img setTransform:m];
200} 200}
201 201
202void
203ns_image_set_smoothing (void *img, bool smooth)
204{
205 [(EmacsImage *)img setSmoothing:smooth];
206}
207
202unsigned long 208unsigned long
203ns_get_pixel (void *img, int x, int y) 209ns_get_pixel (void *img, int x, int y)
204{ 210{
@@ -591,4 +597,10 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
591 [transform setTransformStruct:tm]; 597 [transform setTransformStruct:tm];
592} 598}
593 599
600- (void)setSmoothing: (BOOL) s
601{
602 smoothing = s;
603}
604
605
594@end 606@end
diff --git a/src/nsterm.h b/src/nsterm.h
index 8d5371c8f24..a511fef5b98 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -640,6 +640,7 @@ typedef id instancetype;
640 unsigned long xbm_fg; 640 unsigned long xbm_fg;
641@public 641@public
642 NSAffineTransform *transform; 642 NSAffineTransform *transform;
643 BOOL smoothing;
643} 644}
644+ (instancetype)allocInitFromFile: (Lisp_Object)file; 645+ (instancetype)allocInitFromFile: (Lisp_Object)file;
645- (void)dealloc; 646- (void)dealloc;
@@ -658,6 +659,7 @@ typedef id instancetype;
658- (Lisp_Object)getMetadata; 659- (Lisp_Object)getMetadata;
659- (BOOL)setFrame: (unsigned int) index; 660- (BOOL)setFrame: (unsigned int) index;
660- (void)setTransform: (double[3][3]) m; 661- (void)setTransform: (double[3][3]) m;
662- (void)setSmoothing: (BOOL)s;
661@end 663@end
662 664
663 665
@@ -1200,6 +1202,7 @@ extern int ns_image_width (void *img);
1200extern int ns_image_height (void *img); 1202extern int ns_image_height (void *img);
1201extern void ns_image_set_size (void *img, int width, int height); 1203extern void ns_image_set_size (void *img, int width, int height);
1202extern void ns_image_set_transform (void *img, double m[3][3]); 1204extern void ns_image_set_transform (void *img, double m[3][3]);
1205extern void ns_image_set_smoothing (void *img, bool smooth);
1203extern unsigned long ns_get_pixel (void *img, int x, int y); 1206extern unsigned long ns_get_pixel (void *img, int x, int y);
1204extern void ns_put_pixel (void *img, int x, int y, unsigned long argb); 1207extern void ns_put_pixel (void *img, int x, int y, unsigned long argb);
1205extern void ns_set_alpha (void *img, int x, int y, unsigned char a); 1208extern void ns_set_alpha (void *img, int x, int y, unsigned char a);
diff --git a/src/nsterm.m b/src/nsterm.m
index df7f716f51e..572b859a982 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -4043,10 +4043,22 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
4043 4043
4044 [doTransform concat]; 4044 [doTransform concat];
4045 4045
4046 /* Smoothing is the default, so if we don't want smoothing we
4047 have to turn it off. */
4048 if (! img->smoothing)
4049 [[NSGraphicsContext currentContext]
4050 setImageInterpolation:NSImageInterpolationNone];
4051
4046 [img drawInRect:ir fromRect:ir 4052 [img drawInRect:ir fromRect:ir
4047 operation:NSCompositingOperationSourceOver 4053 operation:NSCompositingOperationSourceOver
4048 fraction:1.0 respectFlipped:YES hints:nil]; 4054 fraction:1.0 respectFlipped:YES hints:nil];
4049 4055
4056 /* Apparently image interpolation is not reset with
4057 restoreGraphicsState, so we have to manually reset it. */
4058 if (! img->smoothing)
4059 [[NSGraphicsContext currentContext]
4060 setImageInterpolation:NSImageInterpolationDefault];
4061
4050 [[NSGraphicsContext currentContext] restoreGraphicsState]; 4062 [[NSGraphicsContext currentContext] restoreGraphicsState];
4051 } 4063 }
4052 4064
diff --git a/src/pdumper.c b/src/pdumper.c
index 28529d63648..de9c06c9d2c 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -4785,15 +4785,15 @@ dump_mmap_contiguous_heap (struct dump_memory_map *maps, int nr_maps,
4785 Beware: the simple patch 2019-03-11T15:20:54Z!eggert@cs.ucla.edu 4785 Beware: the simple patch 2019-03-11T15:20:54Z!eggert@cs.ucla.edu
4786 is worse, as it sometimes frees this storage twice. */ 4786 is worse, as it sometimes frees this storage twice. */
4787 struct dump_memory_map_heap_control_block *cb = calloc (1, sizeof (*cb)); 4787 struct dump_memory_map_heap_control_block *cb = calloc (1, sizeof (*cb));
4788
4789 char *mem;
4790 if (!cb) 4788 if (!cb)
4791 goto out; 4789 goto out;
4790 __lsan_ignore_object (cb);
4791
4792 cb->refcount = 1; 4792 cb->refcount = 1;
4793 cb->mem = malloc (total_size); 4793 cb->mem = malloc (total_size);
4794 if (!cb->mem) 4794 if (!cb->mem)
4795 goto out; 4795 goto out;
4796 mem = cb->mem; 4796 char *mem = cb->mem;
4797 for (int i = 0; i < nr_maps; ++i) 4797 for (int i = 0; i < nr_maps; ++i)
4798 { 4798 {
4799 struct dump_memory_map *map = &maps[i]; 4799 struct dump_memory_map *map = &maps[i];
diff --git a/src/process.c b/src/process.c
index 6e5bcf307ab..15634e4a8b0 100644
--- a/src/process.c
+++ b/src/process.c
@@ -5491,6 +5491,10 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5491 } 5491 }
5492 else 5492 else
5493 { 5493 {
5494#ifdef HAVE_GNUTLS
5495 int tls_nfds;
5496 fd_set tls_available;
5497#endif
5494 /* Set the timeout for adaptive read buffering if any 5498 /* Set the timeout for adaptive read buffering if any
5495 process has non-zero read_output_skip and non-zero 5499 process has non-zero read_output_skip and non-zero
5496 read_output_delay, and we are not reading output for a 5500 read_output_delay, and we are not reading output for a
@@ -5560,7 +5564,36 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5560 } 5564 }
5561#endif 5565#endif
5562 5566
5563/* Non-macOS HAVE_GLIB builds call thread_select in xgselect.c. */ 5567#ifdef HAVE_GNUTLS
5568 /* GnuTLS buffers data internally. We need to check if some
5569 data is available in the buffers manually before the select.
5570 And if so, we need to skip the select which could block. */
5571 FD_ZERO (&tls_available);
5572 tls_nfds = 0;
5573 for (channel = 0; channel < FD_SETSIZE; ++channel)
5574 if (! NILP (chan_process[channel])
5575 && FD_ISSET (channel, &Available))
5576 {
5577 struct Lisp_Process *p = XPROCESS (chan_process[channel]);
5578 if (p
5579 && p->gnutls_p && p->gnutls_state
5580 && emacs_gnutls_record_check_pending (p->gnutls_state) > 0)
5581 {
5582 tls_nfds++;
5583 eassert (p->infd == channel);
5584 FD_SET (p->infd, &tls_available);
5585 }
5586 }
5587 /* If wait_proc is somebody else, we have to wait in select
5588 as usual. Otherwise, clobber the timeout. */
5589 if (tls_nfds > 0
5590 && (!wait_proc ||
5591 (wait_proc->infd >= 0
5592 && FD_ISSET (wait_proc->infd, &tls_available))))
5593 timeout = make_timespec (0, 0);
5594#endif
5595
5596 /* Non-macOS HAVE_GLIB builds call thread_select in xgselect.c. */
5564#if defined HAVE_GLIB && !defined HAVE_NS 5597#if defined HAVE_GLIB && !defined HAVE_NS
5565 nfds = xg_select (max_desc + 1, 5598 nfds = xg_select (max_desc + 1,
5566 &Available, (check_write ? &Writeok : 0), 5599 &Available, (check_write ? &Writeok : 0),
@@ -5578,59 +5611,21 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5578#endif /* !HAVE_GLIB */ 5611#endif /* !HAVE_GLIB */
5579 5612
5580#ifdef HAVE_GNUTLS 5613#ifdef HAVE_GNUTLS
5581 /* GnuTLS buffers data internally. In lowat mode it leaves 5614 /* Merge tls_available into Available. */
5582 some data in the TCP buffers so that select works, but 5615 if (tls_nfds > 0)
5583 with custom pull/push functions we need to check if some
5584 data is available in the buffers manually. */
5585 if (nfds == 0)
5586 { 5616 {
5587 fd_set tls_available; 5617 if (nfds == 0 || (nfds < 0 && errno == EINTR))
5588 int set = 0;
5589
5590 FD_ZERO (&tls_available);
5591 if (! wait_proc)
5592 { 5618 {
5593 /* We're not waiting on a specific process, so loop 5619 /* Fast path, just copy. */
5594 through all the channels and check for data. 5620 nfds = tls_nfds;
5595 This is a workaround needed for some versions of 5621 Available = tls_available;
5596 the gnutls library -- 2.12.14 has been confirmed
5597 to need it. */
5598 for (channel = 0; channel < FD_SETSIZE; ++channel)
5599 if (! NILP (chan_process[channel]))
5600 {
5601 struct Lisp_Process *p =
5602 XPROCESS (chan_process[channel]);
5603 if (p && p->gnutls_p && p->gnutls_state
5604 && ((emacs_gnutls_record_check_pending
5605 (p->gnutls_state))
5606 > 0))
5607 {
5608 nfds++;
5609 eassert (p->infd == channel);
5610 FD_SET (p->infd, &tls_available);
5611 set++;
5612 }
5613 }
5614 }
5615 else
5616 {
5617 /* Check this specific channel. */
5618 if (wait_proc->gnutls_p /* Check for valid process. */
5619 && wait_proc->gnutls_state
5620 /* Do we have pending data? */
5621 && ((emacs_gnutls_record_check_pending
5622 (wait_proc->gnutls_state))
5623 > 0))
5624 {
5625 nfds = 1;
5626 eassert (0 <= wait_proc->infd);
5627 /* Set to Available. */
5628 FD_SET (wait_proc->infd, &tls_available);
5629 set++;
5630 }
5631 } 5622 }
5632 if (set) 5623 else if (nfds > 0)
5633 Available = tls_available; 5624 /* Slow path, merge one by one. Note: nfds does not need
5625 to be accurate, just positive is enough. */
5626 for (channel = 0; channel < FD_SETSIZE; ++channel)
5627 if (FD_ISSET(channel, &tls_available))
5628 FD_SET(channel, &Available);
5634 } 5629 }
5635#endif 5630#endif
5636 } 5631 }
diff --git a/src/ptr-bounds.h b/src/ptr-bounds.h
deleted file mode 100644
index 22d49f25b6c..00000000000
--- a/src/ptr-bounds.h
+++ /dev/null
@@ -1,79 +0,0 @@
1/* Pointer bounds checking for GNU Emacs
2
3Copyright 2017-2020 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or (at
10your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
19
20/* Pointer bounds checking is a no-op unless running on hardware
21 supporting Intel MPX (Intel Skylake or better). Also, it requires
22 GCC 5 and Linux kernel 3.19, or later. Configure with
23 CFLAGS='-fcheck-pointer-bounds -mmpx', perhaps with
24 -fchkp-first-field-has-own-bounds thrown in.
25
26 Although pointer bounds checking can help during debugging, it is
27 disabled by default because it hurts performance significantly.
28 The checking does not detect all pointer errors. For example, a
29 dumped Emacs might not detect a bounds violation of a pointer that
30 was created before Emacs was dumped. */
31
32#ifndef PTR_BOUNDS_H
33#define PTR_BOUNDS_H
34
35#include <stddef.h>
36
37/* When not checking pointer bounds, the following macros simply
38 return their first argument. These macros return either void *, or
39 the same type as their first argument. */
40
41INLINE_HEADER_BEGIN
42
43/* Return a copy of P, with bounds narrowed to [P, P + N). */
44#ifdef __CHKP__
45INLINE void *
46ptr_bounds_clip (void const *p, size_t n)
47{
48 return __builtin___bnd_narrow_ptr_bounds (p, p, n);
49}
50#else
51# define ptr_bounds_clip(p, n) ((void) (size_t) {n}, p)
52#endif
53
54/* Return a copy of P, but with the bounds of Q. */
55#ifdef __CHKP__
56# define ptr_bounds_copy(p, q) __builtin___bnd_copy_ptr_bounds (p, q)
57#else
58# define ptr_bounds_copy(p, q) ((void) (void const *) {q}, p)
59#endif
60
61/* Return a copy of P, but with infinite bounds.
62 This is a loophole in pointer bounds checking. */
63#ifdef __CHKP__
64# define ptr_bounds_init(p) __builtin___bnd_init_ptr_bounds (p)
65#else
66# define ptr_bounds_init(p) (p)
67#endif
68
69/* Return a copy of P, but with bounds [P, P + N).
70 This is a loophole in pointer bounds checking. */
71#ifdef __CHKP__
72# define ptr_bounds_set(p, n) __builtin___bnd_set_ptr_bounds (p, n)
73#else
74# define ptr_bounds_set(p, n) ((void) (size_t) {n}, p)
75#endif
76
77INLINE_HEADER_END
78
79#endif /* PTR_BOUNDS_H */
diff --git a/src/regex-emacs.c b/src/regex-emacs.c
index 1ecbc74b96c..c44cce9f787 100644
--- a/src/regex-emacs.c
+++ b/src/regex-emacs.c
@@ -29,10 +29,6 @@
29 29
30#include <stdlib.h> 30#include <stdlib.h>
31 31
32#ifdef HAVE_SANITIZER_LSAN_INTERFACE_H
33#include <sanitizer/lsan_interface.h>
34#endif
35
36#include "character.h" 32#include "character.h"
37#include "buffer.h" 33#include "buffer.h"
38#include "syntax.h" 34#include "syntax.h"
@@ -1761,9 +1757,7 @@ regex_compile (re_char *pattern, ptrdiff_t size,
1761 /* Initialize the compile stack. */ 1757 /* Initialize the compile stack. */
1762 compile_stack.stack = xmalloc (INIT_COMPILE_STACK_SIZE 1758 compile_stack.stack = xmalloc (INIT_COMPILE_STACK_SIZE
1763 * sizeof *compile_stack.stack); 1759 * sizeof *compile_stack.stack);
1764#ifdef HAVE___LSAN_IGNORE_OBJECT
1765 __lsan_ignore_object (compile_stack.stack); 1760 __lsan_ignore_object (compile_stack.stack);
1766#endif
1767 compile_stack.size = INIT_COMPILE_STACK_SIZE; 1761 compile_stack.size = INIT_COMPILE_STACK_SIZE;
1768 compile_stack.avail = 0; 1762 compile_stack.avail = 0;
1769 1763
diff --git a/src/search.c b/src/search.c
index 7b74ff91480..38c64caf7c0 100644
--- a/src/search.c
+++ b/src/search.c
@@ -21,10 +21,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
21 21
22#include <config.h> 22#include <config.h>
23 23
24#ifdef HAVE_SANITIZER_LSAN_INTERFACE_H
25#include <sanitizer/lsan_interface.h>
26#endif
27
28#include "lisp.h" 24#include "lisp.h"
29#include "character.h" 25#include "character.h"
30#include "buffer.h" 26#include "buffer.h"
@@ -619,9 +615,7 @@ newline_cache_on_off (struct buffer *buf)
619 if (base_buf->newline_cache == 0) 615 if (base_buf->newline_cache == 0)
620 { 616 {
621 base_buf->newline_cache = new_region_cache (); 617 base_buf->newline_cache = new_region_cache ();
622#ifdef HAVE___LSAN_IGNORE_OBJECT
623 __lsan_ignore_object (base_buf->newline_cache); 618 __lsan_ignore_object (base_buf->newline_cache);
624#endif
625 } 619 }
626 } 620 }
627 return base_buf->newline_cache; 621 return base_buf->newline_cache;
diff --git a/src/xdisp.c b/src/xdisp.c
index fc17014c029..4fe1c4288af 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -993,12 +993,12 @@ static void handle_line_prefix (struct it *);
993static void handle_stop_backwards (struct it *, ptrdiff_t); 993static void handle_stop_backwards (struct it *, ptrdiff_t);
994static void unwind_with_echo_area_buffer (Lisp_Object); 994static void unwind_with_echo_area_buffer (Lisp_Object);
995static Lisp_Object with_echo_area_buffer_unwind_data (struct window *); 995static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
996static bool current_message_1 (ptrdiff_t, Lisp_Object); 996static bool current_message_1 (void *, Lisp_Object);
997static bool truncate_message_1 (ptrdiff_t, Lisp_Object); 997static bool truncate_message_1 (void *, Lisp_Object);
998static void set_message (Lisp_Object); 998static void set_message (Lisp_Object);
999static bool set_message_1 (ptrdiff_t, Lisp_Object); 999static bool set_message_1 (void *, Lisp_Object);
1000static bool display_echo_area_1 (ptrdiff_t, Lisp_Object); 1000static bool display_echo_area_1 (void *, Lisp_Object);
1001static bool resize_mini_window_1 (ptrdiff_t, Lisp_Object); 1001static bool resize_mini_window_1 (void *, Lisp_Object);
1002static void unwind_redisplay (void); 1002static void unwind_redisplay (void);
1003static void extend_face_to_end_of_line (struct it *); 1003static void extend_face_to_end_of_line (struct it *);
1004static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t); 1004static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
@@ -11278,8 +11278,8 @@ ensure_echo_area_buffers (void)
11278 11278
11279static bool 11279static bool
11280with_echo_area_buffer (struct window *w, int which, 11280with_echo_area_buffer (struct window *w, int which,
11281 bool (*fn) (ptrdiff_t, Lisp_Object), 11281 bool (*fn) (void *, Lisp_Object),
11282 ptrdiff_t a1, Lisp_Object a2) 11282 void *a1, Lisp_Object a2)
11283{ 11283{
11284 Lisp_Object buffer; 11284 Lisp_Object buffer;
11285 bool this_one, the_other, clear_buffer_p, rc; 11285 bool this_one, the_other, clear_buffer_p, rc;
@@ -11550,8 +11550,7 @@ display_echo_area (struct window *w)
11550 11550
11551 window_height_changed_p 11551 window_height_changed_p
11552 = with_echo_area_buffer (w, display_last_displayed_message_p, 11552 = with_echo_area_buffer (w, display_last_displayed_message_p,
11553 display_echo_area_1, 11553 display_echo_area_1, w, Qnil);
11554 (intptr_t) w, Qnil);
11555 11554
11556 if (no_message_p) 11555 if (no_message_p)
11557 echo_area_buffer[i] = Qnil; 11556 echo_area_buffer[i] = Qnil;
@@ -11568,10 +11567,9 @@ display_echo_area (struct window *w)
11568 Value is true if height of W was changed. */ 11567 Value is true if height of W was changed. */
11569 11568
11570static bool 11569static bool
11571display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2) 11570display_echo_area_1 (void *a1, Lisp_Object a2)
11572{ 11571{
11573 intptr_t i1 = a1; 11572 struct window *w = a1;
11574 struct window *w = (struct window *) i1;
11575 Lisp_Object window; 11573 Lisp_Object window;
11576 struct text_pos start; 11574 struct text_pos start;
11577 11575
@@ -11612,7 +11610,7 @@ resize_echo_area_exactly (void)
11612 struct window *w = XWINDOW (echo_area_window); 11610 struct window *w = XWINDOW (echo_area_window);
11613 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil); 11611 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
11614 bool resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1, 11612 bool resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
11615 (intptr_t) w, resize_exactly); 11613 w, resize_exactly);
11616 if (resized_p) 11614 if (resized_p)
11617 { 11615 {
11618 windows_or_buffers_changed = 42; 11616 windows_or_buffers_changed = 42;
@@ -11630,10 +11628,9 @@ resize_echo_area_exactly (void)
11630 returns. */ 11628 returns. */
11631 11629
11632static bool 11630static bool
11633resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly) 11631resize_mini_window_1 (void *a1, Lisp_Object exactly)
11634{ 11632{
11635 intptr_t i1 = a1; 11633 return resize_mini_window (a1, !NILP (exactly));
11636 return resize_mini_window ((struct window *) i1, !NILP (exactly));
11637} 11634}
11638 11635
11639 11636
@@ -11769,8 +11766,7 @@ current_message (void)
11769 msg = Qnil; 11766 msg = Qnil;
11770 else 11767 else
11771 { 11768 {
11772 with_echo_area_buffer (0, 0, current_message_1, 11769 with_echo_area_buffer (0, 0, current_message_1, &msg, Qnil);
11773 (intptr_t) &msg, Qnil);
11774 if (NILP (msg)) 11770 if (NILP (msg))
11775 echo_area_buffer[0] = Qnil; 11771 echo_area_buffer[0] = Qnil;
11776 } 11772 }
@@ -11780,10 +11776,9 @@ current_message (void)
11780 11776
11781 11777
11782static bool 11778static bool
11783current_message_1 (ptrdiff_t a1, Lisp_Object a2) 11779current_message_1 (void *a1, Lisp_Object a2)
11784{ 11780{
11785 intptr_t i1 = a1; 11781 Lisp_Object *msg = a1;
11786 Lisp_Object *msg = (Lisp_Object *) i1;
11787 11782
11788 if (Z > BEG) 11783 if (Z > BEG)
11789 *msg = make_buffer_string (BEG, Z, true); 11784 *msg = make_buffer_string (BEG, Z, true);
@@ -11857,7 +11852,8 @@ truncate_echo_area (ptrdiff_t nchars)
11857 just an informative message; if the frame hasn't really been 11852 just an informative message; if the frame hasn't really been
11858 initialized yet, just toss it. */ 11853 initialized yet, just toss it. */
11859 if (sf->glyphs_initialized_p) 11854 if (sf->glyphs_initialized_p)
11860 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil); 11855 with_echo_area_buffer (0, 0, truncate_message_1,
11856 (void *) (intptr_t) nchars, Qnil);
11861 } 11857 }
11862} 11858}
11863 11859
@@ -11866,8 +11862,9 @@ truncate_echo_area (ptrdiff_t nchars)
11866 message to at most NCHARS characters. */ 11862 message to at most NCHARS characters. */
11867 11863
11868static bool 11864static bool
11869truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2) 11865truncate_message_1 (void *a1, Lisp_Object a2)
11870{ 11866{
11867 intptr_t nchars = (intptr_t) a1;
11871 if (BEG + nchars < Z) 11868 if (BEG + nchars < Z)
11872 del_range (BEG + nchars, Z); 11869 del_range (BEG + nchars, Z);
11873 if (Z == BEG) 11870 if (Z == BEG)
@@ -11919,7 +11916,7 @@ set_message (Lisp_Object string)
11919 This function is called with the echo area buffer being current. */ 11916 This function is called with the echo area buffer being current. */
11920 11917
11921static bool 11918static bool
11922set_message_1 (ptrdiff_t a1, Lisp_Object string) 11919set_message_1 (void *a1, Lisp_Object string)
11923{ 11920{
11924 eassert (STRINGP (string)); 11921 eassert (STRINGP (string));
11925 11922
@@ -19223,18 +19220,19 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
19223 && !MINI_WINDOW_P (w)) 19220 && !MINI_WINDOW_P (w))
19224 { 19221 {
19225 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS); 19222 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
19223 if (window_wants_header_line (w))
19224 this_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
19226 start_display (&it, w, pos); 19225 start_display (&it, w, pos);
19227 19226
19228 if ((w->cursor.y >= 0 /* not vscrolled */ 19227 if ((w->cursor.y >= 0 /* not vscrolled */
19229 && w->cursor.y < this_scroll_margin 19228 && w->cursor.y < this_scroll_margin
19230 && CHARPOS (pos) > BEGV 19229 && CHARPOS (pos) > BEGV)
19231 && it_charpos < ZV)
19232 /* rms: considering make_cursor_line_fully_visible_p here 19230 /* rms: considering make_cursor_line_fully_visible_p here
19233 seems to give wrong results. We don't want to recenter 19231 seems to give wrong results. We don't want to recenter
19234 when the last line is partly visible, we want to allow 19232 when the last line is partly visible, we want to allow
19235 that case to be handled in the usual way. */ 19233 that case to be handled in the usual way. */
19236 || w->cursor.y > (it.last_visible_y - partial_line_height (&it) 19234 || w->cursor.y > (it.last_visible_y - partial_line_height (&it)
19237 - this_scroll_margin - 1)) 19235 - this_scroll_margin - 1))
19238 { 19236 {
19239 w->cursor.vpos = -1; 19237 w->cursor.vpos = -1;
19240 clear_glyph_matrix (w->desired_matrix); 19238 clear_glyph_matrix (w->desired_matrix);
diff --git a/src/xfns.c b/src/xfns.c
index 2ab5080d977..09dcbbfb92d 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -2652,7 +2652,7 @@ create_frame_xic (struct frame *f)
2652 goto out; 2652 goto out;
2653 2653
2654 xim = FRAME_X_XIM (f); 2654 xim = FRAME_X_XIM (f);
2655 if (!xim) 2655 if (!xim || ! FRAME_X_XIM_STYLES(f))
2656 goto out; 2656 goto out;
2657 2657
2658 /* Determine XIC style. */ 2658 /* Determine XIC style. */