diff options
| author | Paul Eggert | 2014-08-03 05:34:44 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-08-03 05:34:44 -0700 |
| commit | 8f88f7d3c5da38cd2d781770b533dc6c93c52d59 (patch) | |
| tree | a476fa662f618c23f55cfd5999425217f489de92 /src | |
| parent | 5fe16efb24c1b1a89959f7af3c886a4022c8f1b1 (diff) | |
| download | emacs-8f88f7d3c5da38cd2d781770b533dc6c93c52d59.tar.gz emacs-8f88f7d3c5da38cd2d781770b533dc6c93c52d59.zip | |
Avoid undefined behavior with signed left shift.
Caught by 'gcc -fsanitize=undefined'.
* dispextern.h, scroll.c (scrolling_max_lines_saved, scrolling_1):
* dispnew.c (line_hash_code, scrolling):
* scroll.c (calculate_scrolling, calculate_direct_scrolling):
Use 'unsigned', not 'int', for line hashes.
(scrolling_max_lines_saved): Avoid mystery constants for hash sizes.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/dispextern.h | 6 | ||||
| -rw-r--r-- | src/dispnew.c | 8 | ||||
| -rw-r--r-- | src/scroll.c | 20 |
4 files changed, 28 insertions, 16 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 28367ed34f5..dce13035766 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2014-08-03 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Avoid undefined behavior with signed left shift. | ||
| 4 | Caught by 'gcc -fsanitize=undefined'. | ||
| 5 | * dispextern.h, scroll.c (scrolling_max_lines_saved, scrolling_1): | ||
| 6 | * dispnew.c (line_hash_code, scrolling): | ||
| 7 | * scroll.c (calculate_scrolling, calculate_direct_scrolling): | ||
| 8 | Use 'unsigned', not 'int', for line hashes. | ||
| 9 | (scrolling_max_lines_saved): Avoid mystery constants for hash sizes. | ||
| 10 | |||
| 1 | 2014-08-02 Paul Eggert <eggert@cs.ucla.edu> | 11 | 2014-08-02 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 12 | ||
| 3 | Make compare-strings more compatible with old behavior (Bug#17903). | 13 | Make compare-strings more compatible with old behavior (Bug#17903). |
diff --git a/src/dispextern.h b/src/dispextern.h index bb6f1eb2b5e..ebd4260d408 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -3507,13 +3507,13 @@ extern void tty_append_glyph (struct it *); | |||
| 3507 | 3507 | ||
| 3508 | /* Defined in scroll.c */ | 3508 | /* Defined in scroll.c */ |
| 3509 | 3509 | ||
| 3510 | extern int scrolling_max_lines_saved (int, int, int *, int *, int *); | 3510 | extern int scrolling_max_lines_saved (int, int, unsigned *, unsigned *, int *); |
| 3511 | extern void do_line_insertion_deletion_costs (struct frame *, const char *, | 3511 | extern void do_line_insertion_deletion_costs (struct frame *, const char *, |
| 3512 | const char *, const char *, | 3512 | const char *, const char *, |
| 3513 | const char *, const char *, | 3513 | const char *, const char *, |
| 3514 | const char *, int); | 3514 | const char *, int); |
| 3515 | void scrolling_1 (struct frame *, int, int, int, int *, int *, int *, | 3515 | void scrolling_1 (struct frame *, int, int, int, int *, int *, unsigned *, |
| 3516 | int *, int); | 3516 | unsigned *, int); |
| 3517 | 3517 | ||
| 3518 | /* Defined in frame.c */ | 3518 | /* Defined in frame.c */ |
| 3519 | 3519 | ||
diff --git a/src/dispnew.c b/src/dispnew.c index 70862985e66..78df22ddbe2 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -1108,10 +1108,10 @@ prepare_desired_row (struct window *w, struct glyph_row *row, bool mode_line_p) | |||
| 1108 | /* Return a hash code for glyph row ROW, which may | 1108 | /* Return a hash code for glyph row ROW, which may |
| 1109 | be from current or desired matrix of frame F. */ | 1109 | be from current or desired matrix of frame F. */ |
| 1110 | 1110 | ||
| 1111 | static int | 1111 | static unsigned |
| 1112 | line_hash_code (struct frame *f, struct glyph_row *row) | 1112 | line_hash_code (struct frame *f, struct glyph_row *row) |
| 1113 | { | 1113 | { |
| 1114 | int hash = 0; | 1114 | unsigned hash = 0; |
| 1115 | 1115 | ||
| 1116 | if (row->enabled_p) | 1116 | if (row->enabled_p) |
| 1117 | { | 1117 | { |
| @@ -4647,8 +4647,8 @@ scrolling (struct frame *frame) | |||
| 4647 | int unchanged_at_top, unchanged_at_bottom; | 4647 | int unchanged_at_top, unchanged_at_bottom; |
| 4648 | int window_size; | 4648 | int window_size; |
| 4649 | int changed_lines; | 4649 | int changed_lines; |
| 4650 | int *old_hash = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int)); | 4650 | unsigned *old_hash = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int)); |
| 4651 | int *new_hash = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int)); | 4651 | unsigned *new_hash = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int)); |
| 4652 | int *draw_cost = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int)); | 4652 | int *draw_cost = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int)); |
| 4653 | int *old_draw_cost = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int)); | 4653 | int *old_draw_cost = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int)); |
| 4654 | register int i; | 4654 | register int i; |
diff --git a/src/scroll.c b/src/scroll.c index 3da236ca8a6..6c559663f80 100644 --- a/src/scroll.c +++ b/src/scroll.c | |||
| @@ -90,7 +90,7 @@ calculate_scrolling (struct frame *frame, | |||
| 90 | /* matrix is of size window_size + 1 on each side. */ | 90 | /* matrix is of size window_size + 1 on each side. */ |
| 91 | struct matrix_elt *matrix, | 91 | struct matrix_elt *matrix, |
| 92 | int window_size, int lines_below, | 92 | int window_size, int lines_below, |
| 93 | int *draw_cost, int *old_hash, int *new_hash, | 93 | int *draw_cost, unsigned *old_hash, unsigned *new_hash, |
| 94 | int free_at_end) | 94 | int free_at_end) |
| 95 | { | 95 | { |
| 96 | register int i, j; | 96 | register int i, j; |
| @@ -427,7 +427,7 @@ calculate_direct_scrolling (struct frame *frame, | |||
| 427 | struct matrix_elt *matrix, | 427 | struct matrix_elt *matrix, |
| 428 | int window_size, int lines_below, | 428 | int window_size, int lines_below, |
| 429 | int *draw_cost, int *old_draw_cost, | 429 | int *draw_cost, int *old_draw_cost, |
| 430 | int *old_hash, int *new_hash, | 430 | unsigned *old_hash, unsigned *new_hash, |
| 431 | int free_at_end) | 431 | int free_at_end) |
| 432 | { | 432 | { |
| 433 | register int i, j; | 433 | register int i, j; |
| @@ -794,7 +794,7 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix, | |||
| 794 | void | 794 | void |
| 795 | scrolling_1 (struct frame *frame, int window_size, int unchanged_at_top, | 795 | scrolling_1 (struct frame *frame, int window_size, int unchanged_at_top, |
| 796 | int unchanged_at_bottom, int *draw_cost, int *old_draw_cost, | 796 | int unchanged_at_bottom, int *draw_cost, int *old_draw_cost, |
| 797 | int *old_hash, int *new_hash, int free_at_end) | 797 | unsigned *old_hash, unsigned *new_hash, int free_at_end) |
| 798 | { | 798 | { |
| 799 | struct matrix_elt *matrix | 799 | struct matrix_elt *matrix |
| 800 | = alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix); | 800 | = alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix); |
| @@ -829,12 +829,14 @@ scrolling_1 (struct frame *frame, int window_size, int unchanged_at_top, | |||
| 829 | 829 | ||
| 830 | int | 830 | int |
| 831 | scrolling_max_lines_saved (int start, int end, | 831 | scrolling_max_lines_saved (int start, int end, |
| 832 | int *oldhash, int *newhash, | 832 | unsigned *oldhash, unsigned *newhash, |
| 833 | int *cost) | 833 | int *cost) |
| 834 | { | 834 | { |
| 835 | struct { int hash; int count; } lines[01000]; | 835 | enum { LOG2_NLINES = 9 }; |
| 836 | register int i, h; | 836 | enum { NLINES = 1 << LOG2_NLINES }; |
| 837 | register int matchcount = 0; | 837 | struct { unsigned hash; int count; } lines[NLINES]; |
| 838 | int i, h; | ||
| 839 | int matchcount = 0; | ||
| 838 | int avg_length = 0; | 840 | int avg_length = 0; |
| 839 | int threshold; | 841 | int threshold; |
| 840 | 842 | ||
| @@ -855,7 +857,7 @@ scrolling_max_lines_saved (int start, int end, | |||
| 855 | { | 857 | { |
| 856 | if (cost[i] > threshold) | 858 | if (cost[i] > threshold) |
| 857 | { | 859 | { |
| 858 | h = newhash[i] & 0777; | 860 | h = newhash[i] & (NLINES - 1); |
| 859 | lines[h].hash = newhash[i]; | 861 | lines[h].hash = newhash[i]; |
| 860 | lines[h].count++; | 862 | lines[h].count++; |
| 861 | } | 863 | } |
| @@ -865,7 +867,7 @@ scrolling_max_lines_saved (int start, int end, | |||
| 865 | matches between old lines and new. */ | 867 | matches between old lines and new. */ |
| 866 | for (i = start; i < end; i++) | 868 | for (i = start; i < end; i++) |
| 867 | { | 869 | { |
| 868 | h = oldhash[i] & 0777; | 870 | h = oldhash[i] & (NLINES - 1); |
| 869 | if (oldhash[i] == lines[h].hash) | 871 | if (oldhash[i] == lines[h].hash) |
| 870 | { | 872 | { |
| 871 | matchcount++; | 873 | matchcount++; |