fix bug 67156: overload: nomethod(..., '!') return value inverted
Michael Breen [Fri, 11 Dec 2009 17:48:51 +0000 (17:48 +0000)]
gv.c
lib/overload.t

diff --git a/gv.c b/gv.c
index 932b2b8..9743354 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -1902,7 +1902,8 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
            (void)((cv = cvp[off=bool__amg])
                   || (cv = cvp[off=numer_amg])
                   || (cv = cvp[off=string_amg]));
-           postpr = 1;
+           if (cv)
+               postpr = 1;
            break;
         case copy_amg:
           {
@@ -2007,35 +2008,24 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
         case ge_amg:
         case eq_amg:
         case ne_amg:
-          postpr = 1; off=ncmp_amg; break;
+             off = ncmp_amg;
+             break;
         case slt_amg:
         case sle_amg:
         case sgt_amg:
         case sge_amg:
         case seq_amg:
         case sne_amg:
-          postpr = 1; off=scmp_amg; break;
+             off = scmp_amg;
+             break;
         }
-      if (off != -1) cv = cvp[off];
-      if (!cv) {
-       goto not_found;
-      }
+      if ((off != -1) && (cv = cvp[off]))
+          postpr = 1;
+      else
+          goto not_found;
     } else {
     not_found:                 /* No method found, either report or croak */
       switch (method) {
-        case lt_amg:
-        case le_amg:
-        case gt_amg:
-        case ge_amg:
-        case eq_amg:
-        case ne_amg:
-        case slt_amg:
-        case sle_amg:
-        case sgt_amg:
-        case sge_amg:
-        case seq_amg:
-        case sne_amg:
-          postpr = 0; break;
         case to_sv_amg:
         case to_av_amg:
         case to_hv_amg:
index d54068e..39333cf 100644 (file)
@@ -47,7 +47,7 @@ sub numify { 0 + "${$_[0]}" } # Not needed, additional overhead
 package main;
 
 $| = 1;
-use Test::More tests => 605;
+use Test::More tests => 607;
 
 
 $a = new Oscalar "087";
@@ -1420,7 +1420,7 @@ foreach my $op (qw(<=> == != < <= > >=)) {
 }
 
 {
-    # comparison operators with nomethod
+    # comparison operators with nomethod (bug 41546)
     my $warning = "";
     my $method;
 
@@ -1467,6 +1467,21 @@ foreach my $op (qw(<=> == != < <= > >=)) {
 }
 
 {
+    # nomethod called for '!' after attempted fallback
+    my $nomethod_called = 0;
+
+    package nomethod_not;
+    use overload nomethod => sub { $nomethod_called = 'yes'; };
+
+    package main;
+    my $o = bless [], 'nomethod_not';
+    my $res = ! $o;
+
+    is($nomethod_called, 'yes', "nomethod() is called for '!'");
+    is($res, 'yes', "nomethod(..., '!') return value propagates");
+}
+
+{
     # Subtle bug pre 5.10, as a side effect of the overloading flag being
     # stored on the reference rather than the referent. Despite the fact that
     # objects can only be accessed via references (even internally), the