aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorPaul Eggert2013-11-20 22:46:59 -0800
committerPaul Eggert2013-11-20 22:46:59 -0800
commit75360f19c3994ab7a532124b7f5eb92bfe7c82ed (patch)
treeed6a415b319a37144d63bdfe967daff766f4e044 /src/data.c
parentd1a6bccc995f7e1e9d22a386e1aac0d7c888ff18 (diff)
downloademacs-75360f19c3994ab7a532124b7f5eb92bfe7c82ed.tar.gz
emacs-75360f19c3994ab7a532124b7f5eb92bfe7c82ed.zip
Fix recently introduced bool vector overrun.
This was due to an optimization that went awry. Reported by Glenn Morris in <http://lists.gnu.org/archive/html/emacs-devel/2013-11/msg00622.html>. * alloc.c (make_uninit_bool_vector): Don't allocate a dummy word for empty vectors, undoing the 2013-11-18 change. * data.c (bool_vector_binop_driver): Rely on this. Fix bug that occasionally overran the destination. * lisp.h (struct Lisp_Bool_vector): Document this.
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c50
1 files changed, 27 insertions, 23 deletions
diff --git a/src/data.c b/src/data.c
index 33dd11049ec..bdd56bf0f62 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3054,60 +3054,64 @@ bool_vector_binop_driver (Lisp_Object a,
3054 switch (op) 3054 switch (op)
3055 { 3055 {
3056 case bool_vector_exclusive_or: 3056 case bool_vector_exclusive_or:
3057 while (destdata[i] == (adata[i] ^ bdata[i])) 3057 for (; i < nr_words; i++)
3058 if (! (++i < nr_words)) 3058 if (destdata[i] != (adata[i] ^ bdata[i]))
3059 return Qnil; 3059 goto set_dest;
3060 break; 3060 break;
3061 3061
3062 case bool_vector_subsetp: 3062 case bool_vector_subsetp:
3063 case bool_vector_union: 3063 for (; i < nr_words; i++)
3064 while (destdata[i] == (adata[i] | bdata[i])) 3064 if (adata[i] &~ bdata[i])
3065 if (! (++i < nr_words))
3066 return Qnil; 3065 return Qnil;
3066 return Qt;
3067
3068 case bool_vector_union:
3069 for (; i < nr_words; i++)
3070 if (destdata[i] != (adata[i] | bdata[i]))
3071 goto set_dest;
3067 break; 3072 break;
3068 3073
3069 case bool_vector_intersection: 3074 case bool_vector_intersection:
3070 while (destdata[i] == (adata[i] & bdata[i])) 3075 for (; i < nr_words; i++)
3071 if (! (++i < nr_words)) 3076 if (destdata[i] != (adata[i] & bdata[i]))
3072 return Qnil; 3077 goto set_dest;
3073 break; 3078 break;
3074 3079
3075 case bool_vector_set_difference: 3080 case bool_vector_set_difference:
3076 while (destdata[i] == (adata[i] &~ bdata[i])) 3081 for (; i < nr_words; i++)
3077 if (! (++i < nr_words)) 3082 if (destdata[i] != (adata[i] &~ bdata[i]))
3078 return Qnil; 3083 goto set_dest;
3079 break; 3084 break;
3080 } 3085 }
3086
3087 return Qnil;
3081 } 3088 }
3082 3089
3090 set_dest:
3083 switch (op) 3091 switch (op)
3084 { 3092 {
3085 case bool_vector_exclusive_or: 3093 case bool_vector_exclusive_or:
3086 do 3094 for (; i < nr_words; i++)
3087 destdata[i] = adata[i] ^ bdata[i]; 3095 destdata[i] = adata[i] ^ bdata[i];
3088 while (++i < nr_words);
3089 break;
3090
3091 case bool_vector_subsetp:
3092 break; 3096 break;
3093 3097
3094 case bool_vector_union: 3098 case bool_vector_union:
3095 do 3099 for (; i < nr_words; i++)
3096 destdata[i] = adata[i] | bdata[i]; 3100 destdata[i] = adata[i] | bdata[i];
3097 while (++i < nr_words);
3098 break; 3101 break;
3099 3102
3100 case bool_vector_intersection: 3103 case bool_vector_intersection:
3101 do 3104 for (; i < nr_words; i++)
3102 destdata[i] = adata[i] & bdata[i]; 3105 destdata[i] = adata[i] & bdata[i];
3103 while (++i < nr_words);
3104 break; 3106 break;
3105 3107
3106 case bool_vector_set_difference: 3108 case bool_vector_set_difference:
3107 do 3109 for (; i < nr_words; i++)
3108 destdata[i] = adata[i] &~ bdata[i]; 3110 destdata[i] = adata[i] &~ bdata[i];
3109 while (++i < nr_words);
3110 break; 3111 break;
3112
3113 default:
3114 eassume (0);
3111 } 3115 }
3112 3116
3113 return dest; 3117 return dest;