emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Subtle bug in intervals code


From: Andreas Schwab
Subject: Re: Subtle bug in intervals code
Date: Wed, 18 Jul 2012 15:19:07 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)

Dmitry Antipov <address@hidden> writes:

> Commit 109118 (by me) introduces the following change in src/intervals.c, 
> function delete_interval:
>
> @@ -1262,8 +1198,7 @@
>    register INTERVAL parent;
>    ptrdiff_t amt = LENGTH (i);
>
> -  if (amt > 0)                       /* Only used on zero-length intervals 
> now.  */
> -    abort ();
> +  eassert (amt == 0);                /* Only used on zero-length intervals 
> now.  */
>
>    if (ROOT_INTERVAL_P (i))
>      {
>
> Now this eassert traps at interval with negative length. I'm not familiar with
> this subsystem enough to find (possible) bug quickly, so any help is 
> appreciated.

I think this will fix it.  The total length of an interval doesn't
change when it is absorbed by its children.

diff --git a/src/intervals.c b/src/intervals.c
index 5b8d44e..cd1254b 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -1391,10 +1391,6 @@ merge_interval_right (register INTERVAL i)
   register ptrdiff_t absorb = LENGTH (i);
   register INTERVAL successor;
 
-  /* Zero out this interval.  */
-  i->total_length -= absorb;
-  CHECK_TOTAL_LENGTH (i);
-
   /* Find the succeeding interval.  */
   if (! NULL_RIGHT_CHILD (i))      /* It's below us.  Add absorb
                                      as we descend.  */
@@ -1413,6 +1409,10 @@ merge_interval_right (register INTERVAL i)
       return successor;
     }
 
+  /* Zero out this interval.  */
+  i->total_length -= absorb;
+  CHECK_TOTAL_LENGTH (i);
+
   successor = i;
   while (! NULL_PARENT (successor))       /* It's above us.  Subtract as
                                              we ascend.  */
@@ -1447,10 +1447,6 @@ merge_interval_left (register INTERVAL i)
   register ptrdiff_t absorb = LENGTH (i);
   register INTERVAL predecessor;
 
-  /* Zero out this interval.  */
-  i->total_length -= absorb;
-  CHECK_TOTAL_LENGTH (i);
-
   /* Find the preceding interval.  */
   if (! NULL_LEFT_CHILD (i))   /* It's below us. Go down,
                                   adding ABSORB as we go.  */
@@ -1469,9 +1465,13 @@ merge_interval_left (register INTERVAL i)
       return predecessor;
     }
 
+  /* Zero out this interval.  */
+  i->total_length -= absorb;
+  CHECK_TOTAL_LENGTH (i);
+
   predecessor = i;
   while (! NULL_PARENT (predecessor))  /* It's above us.  Go up,
-                                  subtracting ABSORB.  */
+                                          subtracting ABSORB.  */
     {
       if (AM_RIGHT_CHILD (predecessor))
        {

Andreas.

-- 
Andreas Schwab, address@hidden
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."



reply via email to

[Prev in Thread] Current Thread [Next in Thread]