summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Mitchell <davem@fdisolutions.com>2006-05-10 01:32:10 +0000
committerDave Mitchell <davem@fdisolutions.com>2006-05-10 01:32:10 +0000
commit5f2d99664d8a6923d24892ffc0569f4e03e22edd (patch)
tree9d91bd681577184ff755bb9e9978f9a4bea8644d
parent262cbcdb563b9a037afe19e3ef94322ccc35436a (diff)
downloadperl-5f2d99664d8a6923d24892ffc0569f4e03e22edd.tar.gz
disable WARN and DIE hooks during constant folding
p4raw-id: //depot/perl@28148
-rw-r--r--op.c18
-rw-r--r--t/comp/fold.t20
-rw-r--r--util.c2
-rw-r--r--warnings.h3
-rw-r--r--warnings.pl3
5 files changed, 37 insertions, 9 deletions
diff --git a/op.c b/op.c
index 1421e05b72..f5e24fcdea 100644
--- a/op.c
+++ b/op.c
@@ -2135,6 +2135,8 @@ Perl_fold_constants(pTHX_ register OP *o)
int ret = 0;
I32 oldscope;
OP *old_next;
+ SV * const oldwarnhook = PL_warnhook;
+ SV * const olddiehook = PL_diehook;
dJMPENV;
if (PL_opargs[type] & OA_RETSCALAR)
@@ -2196,6 +2198,8 @@ Perl_fold_constants(pTHX_ register OP *o)
oldscope = PL_scopestack_ix;
create_eval_scope(G_FAKINGEVAL);
+ PL_warnhook = PERL_WARNHOOK_FATAL;
+ PL_diehook = NULL;
JMPENV_PUSH(ret);
switch (ret) {
@@ -2209,11 +2213,6 @@ Perl_fold_constants(pTHX_ register OP *o)
SvTEMP_off(sv);
}
break;
- case 2:
- /* my_exit() was called; propagate it */
- JMPENV_POP;
- JMPENV_JUMP(2);
- /* NOTREACHED */
case 3:
/* Something tried to die. Abandon constant folding. */
/* Pretend the error never happened. */
@@ -2222,11 +2221,16 @@ Perl_fold_constants(pTHX_ register OP *o)
break;
default:
JMPENV_POP;
- /* Don't expect 1 (setjmp failed) */
+ /* Don't expect 1 (setjmp failed) or 2 (something called my_exit) */
+ PL_warnhook = oldwarnhook;
+ PL_diehook = olddiehook;
+ /* XXX note that this croak may fail as we've already blown away
+ * the stack - eg any nested evals */
Perl_croak(aTHX_ "panic: fold_constants JMPENV_PUSH returned %d", ret);
}
-
JMPENV_POP;
+ PL_warnhook = oldwarnhook;
+ PL_diehook = olddiehook;
if (PL_scopestack_ix > oldscope)
delete_eval_scope();
diff --git a/t/comp/fold.t b/t/comp/fold.t
index f063c20622..92a4fbe3e4 100644
--- a/t/comp/fold.t
+++ b/t/comp/fold.t
@@ -8,7 +8,7 @@ BEGIN {
use strict;
use warnings;
-plan (8);
+plan (13);
# Historically constant folding was performed by evaluating the ops, and if
# they threw an exception compilation failed. This was seen as buggy, because
@@ -17,6 +17,7 @@ plan (8);
# making constant folding consistent with many other languages, and purely an
# optimisation rather than a behaviour change.
+
my $a;
$a = eval '$b = 0/0 if 0; 3';
is ($a, 3);
@@ -36,3 +37,20 @@ $a = eval q{
is ($a, 5);
is ($@, "");
+# warn and die hooks should be disabled during constant folding
+
+{
+ my $c = 0;
+ local $SIG{__WARN__} = sub { $c++ };
+ local $SIG{__DIE__} = sub { $c+= 2 };
+ eval q{
+ is($c, 0, "premature warn/die: $c");
+ my $x = "a"+5;
+ is($c, 1, "missing warn hook");
+ is($x, 5, "a+5");
+ $c = 0;
+ $x = 1/0;
+ };
+ like ($@, qr/division/, "eval caught division");
+ is($c, 2, "missing die hook");
+}
diff --git a/util.c b/util.c
index ba531b4722..fb461ccfee 100644
--- a/util.c
+++ b/util.c
@@ -1456,7 +1456,7 @@ void
Perl_vwarner(pTHX_ U32 err, const char* pat, va_list* args)
{
dVAR;
- if (ckDEAD(err)) {
+ if (PL_warnhook == PERL_WARNHOOK_FATAL || ckDEAD(err)) {
SV * const msv = vmess(pat, args);
STRLEN msglen;
const char * const message = SvPV_const(msv, msglen);
diff --git a/warnings.h b/warnings.h
index aa830c05fe..423a21a4c2 100644
--- a/warnings.h
+++ b/warnings.h
@@ -24,6 +24,9 @@
#define specialWARN(x) ((x) == pWARN_STD || (x) == pWARN_ALL || \
(x) == pWARN_NONE)
+/* if PL_warnhook is set to this value, then warnings die */
+#define PERL_WARNHOOK_FATAL (((SV*)0) + 1)
+
/* Warnings Categories added in Perl 5.008 */
#define WARN_ALL 0
diff --git a/warnings.pl b/warnings.pl
index 853a04a1a7..0cb5bbd660 100644
--- a/warnings.pl
+++ b/warnings.pl
@@ -282,6 +282,9 @@ print WARN <<'EOM' ;
#define specialWARN(x) ((x) == pWARN_STD || (x) == pWARN_ALL || \
(x) == pWARN_NONE)
+
+/* if PL_warnhook is set to this value, then warnings die */
+#define PERL_WARNHOOK_FATAL (((SV*)0) + 1)
EOM
my $offset = 0 ;