
hv at crypt
Dec 4, 2009, 7:29 AM
Post #1 of 2
(290 views)
Permalink
|
|
[PATCH] Re: [perl #71000] Wrong variable name in warning
|
|
Abigail <abigail [at] abigail> wrote: :On Wed, Dec 02, 2009 at 06:50:42AM -0800, mauzo [at] osiris (via RT) wrote: :> ~/src/perl/perl% ./perl -we'my $x = 1; my $y = sprintf "%d" . $x' :> Use of uninitialized value $x in sprintf at -e line 1. :> :> Note the typo: dot for comma. : : :It's triggered by sprintf looking for a value to interpolate. :Here's another way to trigger this bug: : : my $format = "%d"; my $y = sprintf $format; I suggest the right thing is to emit a more specific warning in this case, as per the patch below. But I doubt this is [important + safe] enough to warrant applying during the feature freeze. With the patch applied: zen% ./perl -we'my $x = 1; my $y = sprintf "%d" . $x' Missing argument in sprintf at -e line 1. zen% ./perl -we 'my $format = "%d"; my $y = sprintf $format' Missing argument in sprintf at -e line 1. zen% As per the comment, I'm not sure if we'd want a new category for the new warning. As written, it won't suddenly start warning where it didn't before (which may or may not be a good thing). I'm also not sure if the first change to t/op/sprintf2.t below is the best approach. Apart from anything else, it should probably be changed to test that sv_no (as well as/instead of sv_undef) is not getting corrupted. This patch requires the patch to t/test.pl I sent earlier today. Hugo --- sv.c.old 2009-11-24 10:05:09.000000000 +0000 +++ sv.c 2009-12-04 14:17:55.000000000 +0000 @@ -9161,6 +9161,22 @@ sv_vcatpvfn(sv, pat, patlen, args, svargs, svmax, maybe_tainted); } + +/* + * Warn of missing argument to sprintf, and then return a defined value + * to avoid inappropriate "use of uninit" warnings [perl #71000]. + */ +#define WARN_MISSING WARN_UNINITIALIZED /* Not sure we want a new category */ +STATIC SV* +S_vcatpvfn_missing_argument(pTHX_) { + if (ckWARN(WARN_MISSING)) { + Perl_warner(aTHX_ packWARN(WARN_MISSING), "Missing argument in %s", + PL_op ? OP_DESC(PL_op) : "sv_vcatpvfn()"); + } + return &PL_sv_no; +} + + STATIC I32 S_expect_number(pTHX_ char **const pattern) { @@ -9526,9 +9542,10 @@ vecsv = va_arg(*args, SV*); else if (evix) { vecsv = (evix > 0 && evix <= svmax) - ? svargs[evix-1] : &PL_sv_undef; + ? svargs[evix-1] : S_vcatpvfn_missing_argument(); } else { - vecsv = svix < svmax ? svargs[svix++] : &PL_sv_undef; + vecsv = svix < svmax + ? svargs[svix++] : S_vcatpvfn_missing_argument(); } dotstr = SvPV_const(vecsv, dotstrlen); /* Keep the DO_UTF8 test *after* the SvPV call, else things go @@ -9675,10 +9692,11 @@ if (!vectorize && !args) { if (efix) { const I32 i = efix-1; - argsv = (i >= 0 && i < svmax) ? svargs[i] : &PL_sv_undef; + argsv = (i >= 0 && i < svmax) + ? svargs[i] : S_vcatpvfn_missing_argument(); } else { argsv = (svix >= 0 && svix < svmax) - ? svargs[svix++] : &PL_sv_undef; + ? svargs[svix++] : S_vcatpvfn_missing_argument(); } } --- pod/perldiag.pod.old 2009-11-21 19:02:10.000000000 +0000 +++ pod/perldiag.pod 2009-12-04 14:20:46.000000000 +0000 @@ -2425,6 +2425,11 @@ (W syntax) An underscore (underbar) in a numeric constant did not separate two digits. +=item Missing argument in %s + +(W uninitialized) A printf-type format required more arguments than were +supplied. + =item Missing argument to -%c (F) The argument to the indicated command line switch must follow --- t/op/sprintf.t.old 2009-11-19 16:51:40.000000000 +0000 +++ t/op/sprintf.t 2009-12-04 14:16:48.000000000 +0000 @@ -60,6 +60,8 @@ $w = ' INVALID'; } elsif ($_[0] =~ /^Use of uninitialized value/) { $w = ' UNINIT'; + } elsif ($_[0] =~ /^Missing argument/) { + $w = ' MISSING'; } else { warn @_; } @@ -618,7 +620,7 @@ >%3$d %d %d< >[12, 34, 56]< >56 12 34< >%2$*3$d %d< >[12, 34, 3]< > 34 12< >%*3$2$d %d< >[12, 34, 3]< >%*3$2$d 12 INVALID< ->%2$d< >12< >0 UNINIT< +>%2$d< >12< >0 MISSING< >%0$d< >12< >%0$d INVALID< >%1$$d< >12< >%1$$d INVALID< >%1$1$d< >12< >%1$1$d INVALID< @@ -685,4 +687,4 @@ >%#o< >0< >0< >%#x< >0< >0< >%2147483647$v2d< >''< >< ->%*2147483647$v2d< >''< > UNINIT< +>%*2147483647$v2d< >''< > MISSING< --- t/op/sprintf2.t.old 2009-11-19 16:51:40.000000000 +0000 +++ t/op/sprintf2.t 2009-12-04 14:48:38.000000000 +0000 @@ -41,9 +41,9 @@ } # Used to mangle PL_sv_undef -fresh_perl_is( +fresh_perl_like( 'print sprintf "xxx%n\n"; print undef', - 'Modification of a read-only value attempted at - line 1.', + 'Modification of a read-only value attempted at - line 1\.', { switches => [ '-w' ] }, q(%n should not be able to modify read-only constants), ); @@ -60,7 +60,7 @@ { my ($warn, $bad) = (0,0); local $SIG{__WARN__} = sub { - if ($_[0] =~ /uninitialized/) { + if ($_[0] =~ /missing argument/i) { $warn++ } else {
|