Skip to content

Commit d9c9484

Browse files
committed
octave.cxx: fix exception raising for newer Octave versions
- Since (at least) Octave 5.1.0, the Octave error() function now raises a C++ exception, which if uncaught immediately exits a SWIG wrapper function, bypassing any cleanup code that may appear after a "fail:" label. - This patch adds a "try { ... } catch(...) { }" block around the contents of SWIG wrapper functions to first execute the cleanup code before rethrowing any exception raised. - It is backward compatible with earlier versions of Octave where error() does not raise an exception, which will still branch to the "fail:" block to execute cleanup code if an error is encountered.
1 parent e67f125 commit d9c9484

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

CHANGES.current

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,22 @@ Version 4.0.2 (in progress)
1616
2020-05-24: vapier
1717
[JS] #1796 Fix pkg-config invocation in configure.
1818

19+
2020-04-30: kwwette
20+
[Octave] Fix exception raising for newer Octave versions
21+
Since (at least) Octave 5.1.0, the Octave error() function now raises a C++ exception,
22+
which if uncaught immediately exits a SWIG wrapper function, bypassing any cleanup code
23+
that may appear after a "fail:" label. This patch adds a "try { ... } catch(...) { }"
24+
block around the contents of SWIG wrapper functions to first execute the cleanup code
25+
before rethrowing any exception raised. It is backward compatible with earlier versions
26+
of Octave where error() does not raise an exception, which will still branch to the
27+
"fail:" block to execute cleanup code if an error is encountered.
28+
29+
Note that the new "try { ... } catch(...) { }" block will localise any local variables
30+
used in typemaps that were NOT declared through SWIG's %typemap(...) syntax, so it's
31+
possible this could break existing SWIG wrappers which were implicitly sharing local
32+
variables between typemaps. This can be fixed, however, by declaring local variables
33+
which need to be shared between typemaps through SWIG's %typemap(...) syntax.
34+
1935
2020-02-18: ryannevell
2036
[Lua] #1728 Add support for LUA lightuserdata to SWIG_Lua_ConvertPtr.
2137

Source/Modules/octave.cxx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,10 @@ class OCTAVE:public Language {
567567
Wrapper *f = NewWrapper();
568568
Octave_begin_function(n, f->def, iname, overname, !overloaded);
569569

570+
// Start default try block to execute
571+
// cleanup code if exception is thrown
572+
Printf(f->code, "try {\n");
573+
570574
emit_parameter_variables(l, f);
571575
emit_attach_parmmaps(l, f);
572576
Setattr(n, "wrap:parms", l);
@@ -754,9 +758,20 @@ class OCTAVE:public Language {
754758
}
755759

756760
Printf(f->code, "return _out;\n");
757-
Printf(f->code, "fail:\n"); // we should free locals etc if this happens
761+
762+
// Execute cleanup code if branched to fail: label
763+
Printf(f->code, "fail:\n");
758764
Printv(f->code, cleanup, NIL);
759765
Printf(f->code, "return octave_value_list();\n");
766+
767+
// Execute cleanup code if exception was thrown
768+
Printf(f->code, "}\n");
769+
Printf(f->code, "catch(...) {\n");
770+
Printv(f->code, cleanup, NIL);
771+
Printf(f->code, "throw;\n");
772+
Printf(f->code, "}\n");
773+
774+
// End wrapper function
760775
Printf(f->code, "}\n");
761776

762777
/* Substitute the cleanup code */

0 commit comments

Comments
 (0)