REBOL3 tracker
  0.9.12 beta
Ticket #0001509 User: anonymous

Project:



rss
TypeBug Statusbuilt Date3-Mar-2010 22:20
Versionalpha 97 CategoryError Handling Submitted byBrianH
PlatformAll Severitymajor Priorityhigh

Summary Unwind functions don't propagate when called in function arg expression that accepts error! values
Description The structured escape functions are BREAK, CONTINUE, THROW, EXIT and RETURN; the terms "unwinds" and "unwind functions" are used herein for brevity.

Unwind functions do their work by returning a special error! value - not the same type that you can create with MAKE error!. When one of these values is returned from a function, execution of the code that called the function is stopped and the value is returned again, propagating up the call stack, unwinding the stack and cleaning up as it goes, until they are caught by special handlers (loops, CATCH, function calls, the console). See http://www.rebol.com/r3/notes/errors.html for details.

However, there is a quirk: When an unwind value is returned from a function, if that function call expression would return to the argument list of a function that accepts error! or any-type! arguments, then the unwind stops propagating and is passed as an argument value. This quirk is arguably a *major* bug because of how many functions we have that accept error! arguments, such as TYPE?, ERROR?, all of the type checking functions, and ironically THROW and RETURN themselves.

This bug doesn't affect the throwing of regular errors when they've been triggered, nor does it affect the treatment of errors that haven't been triggered yet or were already caught by TRY or ATTEMPT. It's only the unwind pseudo-errors, and only when the expressions that generate them are passed as function arguments to functions that accept error! values.

The theoretical fix for this bug would be to fix function argument evaluation in DO and APPLY so that when unwinds are encountered they are propagated safely, even if the function argument accepts error!. Only untriggered normal error! values should be passed as an argument to the function, not unwinds. This shouldn't affect the top-level error handler because unwinds aren't thrown like regular errors, they are return values.

See also #771 and #862, which illustrate specific cases of the larger problem. #851 might be related.
Example code
>> error? break
== true
; The unwind is passed to the ERROR? function instead of propagated.
; Should be ** Throw error: no loop to break

>> loop 1 [error? break/return "good" "buggy"]
== "buggy"  ; Should be "good"

; This is good (though see #1506)
>> attempt [break]
** Throw error: no loop to break
; This is bad, should trigger the same error
>> type? attempt [break]
== error!

; Common code patterns
>> loop 1 [break print "This should not be printed!"]
>> loop 1 [try [break] print "This should not be printed!"]
>> loop 1 [error? try [break] print "This should not be printed!"]
This should not be printed!
>> loop 1 [attempt [break] print "This should not be printed!"]
>> loop 1 [type? attempt [break] print "This should not be printed!"]
This should not be printed!

Assigned ton/a Fixed inr3 master Last Update19-Feb-2014 20:01


Comments
(0002070)
BrianH
7-Mar-2010 21:57

Fixed the phrasing to match the description of error processing and unwind handling described here: http://www.rebol.com/r3/notes/errors.html
(0002073)
Ladislav
8-Mar-2010 15:39

I think, that the bugs #771 and #1509 are caused by mixing the "internal" and "external" datatypes - an "internal unwind" (also "triggered unwind"/"caused unwind"/"activated unwind" - an unwind *already used* to unwind the execution back to a marker) should not be the same as an "external unwind" (also "untriggered unwind"/"inactive unwind" - a value, which is/can be manipulated by the interpreter as a "Rebol value")
(0002080)
Ladislav
9-Mar-2010 10:51

Regarding:

; This is good
>> attempt [break]
** Throw error: no loop to break

As far as #1506 is concerned, the above behaviour is not good.
(0002082)
BrianH
9-Mar-2010 12:34

No, that behavior is good. The ATTEMPT is called before the BREAK, not afterwards, so it is passed the code block containing the BREAK as an argument, not the result of the BREAK. It's the result of the BREAK that is the problem, not the code block containing the original expression.

For an example of really nasty code, see #1515: Apparently the set-word assignment of errors also lets you assign unwinds, and when you DO the saved value it is like executing the unwind function again. This lets you break a sandbox in the way that #1004 was supposed to fix. This is really bad.
(0002087)
Sunanda
11-Mar-2010 10:23

I posted this in the REBOL3 Blog. Ladislav has suggested I also ensure it is in the CureCode records:

To document two issues that may be related to this:

First:

do "while [] []"

is bad when executed in the console, but good when executed in a script:

attempt [do "while [] []"]

Second: R2 and R3 respond differently here (I am aware of Curecode #666):

while [return 55][print 1]

Some discussion of these examples here:

http://www.rebol.org/aga-display-posts.r?post=r3wp771x1494
(0002090)
Ladislav
12-Mar-2010 10:32

Sorry, Brian, you are right, that as far as #1509 is concerned, the behaviour may be considered OK, but, as far as #1506 is concerned, it is a bug.
(0002092)
BrianH
12-Mar-2010 18:37

Sunanda, the first of those is because of #851, and the second is related to #1509 but not quite the same thing; see #1519 for details.

Tweaked the wording to reflect new information, and to mention #1506.
(0002112)
BrianH
23-Mar-2010 17:41

New crash bug that is a side effect of this: #1535.
(0002757)
Ladislav
2-Nov-2010 12:19

in the core-tests suite
(0002839)
abolka
11-Nov-2010 23:50

QUIT and HALT are "throws" not "unwindws" and unaffected by this.
(0002842)
BrianH
12-Nov-2010 07:42

Thanks, Andreas. I had noticed that earlier this week (much to my surprise, for some reason), but had not fixed the description in this ticket. It's fixed now.

Date User Field Action Change
19-Feb-2014 20:01 BrianH Status Modified submitted => built
19-Feb-2014 20:01 BrianH Fixedin Modified => r3 master
12-Nov-2010 07:42 BrianH Comment : 0002842 Added -
12-Nov-2010 07:40 BrianH Description Modified -
11-Nov-2010 23:50 abolka Comment : 0002839 Added -
2-Nov-2010 12:19 Ladislav Comment : 0002757 Added -
2-Nov-2010 00:39 BrianH Code Modified -
23-Mar-2010 17:41 BrianH Comment : 0002112 Added -
12-Mar-2010 22:37 BrianH Comment : 0002092 Modified -
12-Mar-2010 22:36 BrianH Code Modified -
12-Mar-2010 22:36 BrianH Summary Modified All structured escape functions are disabled when they are called in an expression that accepts error! values => Unwind functions don't propagate when called in function arg expression that accepts error! values
12-Mar-2010 22:36 BrianH Description Modified -
12-Mar-2010 22:25 BrianH Comment : 0002092 Modified -
12-Mar-2010 18:37 BrianH Comment : 0002092 Added -
12-Mar-2010 10:32 Ladislav Comment : 0002090 Added -
12-Mar-2010 10:31 Ladislav Comment : 0002080 Modified -
11-Mar-2010 10:23 sunanda Comment : 0002087 Added -
9-Mar-2010 12:35 BrianH Comment : 0002082 Modified -
9-Mar-2010 12:35 BrianH Priority Modified normal => high
9-Mar-2010 12:34 BrianH Comment : 0002082 Added -
9-Mar-2010 10:51 Ladislav Comment : 0002080 Added -
9-Mar-2010 10:50 Ladislav Comment : 0002073 Modified -
8-Mar-2010 15:39 Ladislav Comment : 0002073 Added -
8-Mar-2010 15:19 Ladislav Comment : 0002068 Removed -
7-Mar-2010 21:57 BrianH Comment : 0002070 Added -
7-Mar-2010 21:56 BrianH Code Modified -
7-Mar-2010 21:56 BrianH Description Modified -
4-Mar-2010 09:54 Ladislav Comment : 0002068 Modified -
4-Mar-2010 09:54 Ladislav Comment : 0002068 Added -
4-Mar-2010 09:53 Ladislav Comment : 0002067 Removed -
4-Mar-2010 09:48 Ladislav Comment : 0002067 Added -
4-Mar-2010 09:45 Ladislav Comment : 0002066 Removed -
4-Mar-2010 09:43 Ladislav Comment : 0002066 Added -
3-Mar-2010 22:55 BrianH Description Modified -
3-Mar-2010 22:53 BrianH Description Modified -
3-Mar-2010 22:52 BrianH Description Modified -
3-Mar-2010 22:21 BrianH Code Modified -
3-Mar-2010 22:21 BrianH Description Modified -
3-Mar-2010 22:21 BrianH Summary Modified All structured escape functions are disabled when they are in an expression that accepts error! values => All structured escape functions are disabled when they are called in an expression that accepts error! values
3-Mar-2010 22:20 BrianH Ticket Added -