Skip to content

Commit d8999d8

Browse files
committed
Leave catching context before resuming jump
So the exception object can be destructed properly
1 parent f226bb7 commit d8999d8

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

ChangeLog

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
frame environment returns from that frame rather than from the
3131
Rcpp_eval() call.
3232

33+
* inst/include/Rcpp/macros/macros.h: Leave the try/catch scope before
34+
resuming jump to ensure proper destruction of the exception reference.
35+
3336
2018-05-09 Dirk Eddelbuettel <[email protected]>
3437

3538
* DESCRIPTION: Release 0.12.17

inst/include/Rcpp/macros/macros.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@
4242
rcpp_output_type = 1 ; \
4343
} \
4444
catch(Rcpp::internal::LongjumpException& __ex__) { \
45-
Rcpp::internal::resumeJump(__ex__.token); \
46-
rcpp_output_type = 2 ; \
47-
rcpp_output_condition = PROTECT(string_to_try_error("Unexpected LongjumpException")) ; \
45+
rcpp_output_type = 3 ; \
46+
rcpp_output_condition = __ex__.token; \
4847
} \
4948
catch(Rcpp::exception& __ex__) { \
5049
rcpp_output_type = 2 ; \
@@ -65,29 +64,40 @@
6564
SEXP stop_sym = Rf_install( "stop" ) ; \
6665
SEXP expr = PROTECT( Rf_lang2( stop_sym , rcpp_output_condition ) ) ; \
6766
Rf_eval( expr, R_GlobalEnv ) ; \
67+
} \
68+
if (rcpp_output_type == 3) { \
69+
Rcpp::internal::resumeJump(rcpp_output_condition); \
70+
Rf_error("Internal error: Rcpp longjump failed to resume"); \
6871
}
6972
#endif
7073

7174
#ifndef END_RCPP
7275
#define END_RCPP VOID_END_RCPP return R_NilValue;
7376
#endif
7477

78+
79+
// There is no return in case of a longjump exception
80+
7581
#ifndef END_RCPP_RETURN_ERROR
7682
#define END_RCPP_RETURN_ERROR \
7783
} \
7884
catch (Rcpp::internal::InterruptedException &__ex__) { \
7985
return Rcpp::internal::interruptedError(); \
8086
} \
8187
catch (Rcpp::internal::LongjumpException& __ex__) { \
82-
Rcpp::internal::resumeJump(__ex__.token); \
83-
return string_to_try_error("Unexpected LongjumpException") ; \
88+
rcpp_output_type = 3 ; \
89+
rcpp_output_condition = __ex__.token; \
8490
} \
8591
catch (std::exception &__ex__) { \
8692
return exception_to_try_error(__ex__); \
8793
} \
8894
catch (...) { \
8995
return string_to_try_error("c++ exception (unknown reason)"); \
9096
} \
97+
if (rcpp_output_type == 3) { \
98+
Rcpp::internal::resumeJump(rcpp_output_condition); \
99+
Rf_error("Internal error: Rcpp longjump failed to resume"); \
100+
} \
91101
return R_NilValue;
92102
#endif
93103

0 commit comments

Comments
 (0)