This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix err message for $cond ? \bad : ... = ...
authorFather Chrysostomos <sprout@cpan.org>
Thu, 2 Oct 2014 03:18:06 +0000 (20:18 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 11 Oct 2014 07:10:15 +0000 (00:10 -0700)
The error message code in S_lvref was assuming that it only handled
list assignment (which was originally the case), but

    $condition ? \pos : whatever = ...

goes through that same code path, and that is a scalar assignment.

So pass the assignment type through to S_lvref.

op.c
t/op/lvref.t

diff --git a/op.c b/op.c
index 5cafa05..0d727c0 100644 (file)
--- a/op.c
+++ b/op.c
@@ -2336,14 +2336,14 @@ S_vivifies(const OPCODE type)
 }
 
 static void
-S_lvref(pTHX_ OP *o)
+S_lvref(pTHX_ OP *o, I32 type)
 {
     OP *kid;
     switch (o->op_type) {
     case OP_COND_EXPR:
        for (kid = OP_SIBLING(cUNOPo->op_first); kid;
             kid = OP_SIBLING(kid))
-           S_lvref(aTHX_ kid);
+           S_lvref(aTHX_ kid, type);
        /* FALLTHROUGH */
     case OP_PUSHMARK:
        return;
@@ -2423,14 +2423,14 @@ S_lvref(pTHX_ OP *o)
        else if (!(o->op_flags & OPf_KIDS))
            return;
        if (o->op_targ != OP_LIST) {
-           S_lvref(aTHX_ cBINOPo->op_first);
+           S_lvref(aTHX_ cBINOPo->op_first, type);
            return;
        }
        /* FALLTHROUGH */
     case OP_LIST:
        for (kid = cLISTOPo->op_first; kid; kid = OP_SIBLING(kid)) {
            assert((kid->op_flags & OPf_WANT) != OPf_WANT_VOID);
-           S_lvref(aTHX_ kid);
+           S_lvref(aTHX_ kid, type);
        }
        return;
     case OP_STUB:
@@ -2440,11 +2440,11 @@ S_lvref(pTHX_ OP *o)
     default:
       badref:
        /* diag_listed_as: Can't modify %s in %s */
-       yyerror(Perl_form(aTHX_ "Can't modify reference to %s in list "
-                               "assignment",
+       yyerror(Perl_form(aTHX_ "Can't modify reference to %s in %s",
                     o->op_type == OP_NULL && o->op_flags & OPf_SPECIAL
                      ? "do block"
-                     : OP_DESC(o)));
+                     : OP_DESC(o),
+                    PL_op_desc[type]));
        return;
     }
     o->op_type = OP_LVREF;
@@ -2758,7 +2758,7 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags)
       kid_2lvref:
        {
            const U8 ec = PL_parser ? PL_parser->error_count : 0;
-           S_lvref(aTHX_ kid);
+           S_lvref(aTHX_ kid, type);
            if (!PL_parser || PL_parser->error_count == ec) {
                if (!FEATURE_LVREF_IS_ENABLED)
                    Perl_croak(aTHX_
index bfdd737..bdaa23e 100644 (file)
@@ -4,7 +4,7 @@ BEGIN {
     set_up_inc("../lib");
 }
 
-plan 124;
+plan 125;
 
 sub on { $::TODO = ' ' }
 sub off{ $::TODO = ''  }
@@ -424,6 +424,10 @@ eval '\%{"42"} = 42';
 like $@,
     qr/^Can't modify reference to hash dereference in scalar assignment a/,
    "Can't modify reference to hash dereference in scalar assignment";
+eval '$foo ? \%{"42"} : \%43 = 42';
+like $@,
+    qr/^Can't modify reference to hash dereference in scalar assignment a/,
+   "Can't modify ref to whatever in scalar assignment via cond expr";
 on;