# New Ticket Created by l.mai@web.de # Please include the string: [perl #122966] # in the subject line of all future correspondence about this issue. # <URL: https://rt.perl.org/Ticket/Display.html?id=122966 > The Problem ----------- Consider this code: #!perl use strict; use warnings; if (1 { my $wtf = 42; print "$wtf\n"; } __END__ If you run that, you get: "my" variable $wtf masks earlier declaration in same statement at foo.pl line 7. syntax error at foo.pl line 5, near "1 {" syntax error at foo.pl line 8, near "}" Execution of foo.pl aborted due to compilation errors. I.e. there's a bogus warning on line 7, then the actual error on line 5. Now the same code with fatal warnings: #!perl use strict; use warnings FATAL => 'all'; if (1 { my $wtf = 42; print "$wtf\n"; } __END__ This time the output is just: "my" variable $wtf masks earlier declaration in same statement at bar.pl line 7. The actual error is completely hidden because the bogus warning throws an exception and aborts everything. My Solution ----------- I've attached a patch that solves this problem by simply defatalizing warnings if we're currently parsing and there are pending parse errors. I think this is a good way to handle this situation because we don't know whether the warning we're about to emit is useful or caused by misinterpretation of the code after a syntax error. So we warn non-fatally because the pending parse errors will throw an exception later on anyway. Thoughts? (Patch copied inline here because I don't know whether attaching or inline code is the preferred method.) >From f3aa466b4080470e3a14071cb476674e9bfdf796 Mon Sep 17 00:00:00 2001 From: Lukas Mai <l.mai@web.de> Date: Sun, 12 Oct 2014 19:01:09 +0200 Subject: [PATCH] don't fatalize warnings after syntax errors --- util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util.c b/util.c index ae3b833..0689d7c 100644 --- a/util.c +++ b/util.c @@ -1911,7 +1911,8 @@ Perl_vwarner(pTHX_ U32 err, const char* pat, va_list* args) { dVAR; PERL_ARGS_ASSERT_VWARNER; - if (PL_warnhook == PERL_WARNHOOK_FATAL || ckDEAD(err)) { + if ((PL_warnhook == PERL_WARNHOOK_FATAL || ckDEAD(err)) + && !(PL_parser && PL_parser->error_count)) { SV * const msv = vmess(pat, args); invoke_exception_hook(msv, FALSE); -- 2.1.2Thread Previous