develooper Front page | perl.perl5.porters | Postings from January 2012

Re: defined(@arr), defined (%hash)

Thread Previous | Thread Next
From:
wolfsage
Date:
January 15, 2012 11:18
Subject:
Re: defined(@arr), defined (%hash)
Message ID:
CAJ0K8bgL7Y5sM1XZXhez+N_i29HNm16yHmv+0-svEV5NCgtc5A@mail.gmail.com
From 2f78616dba3375b396fe17607d2216c4651d307d Mon Sep 17 00:00:00 2001
From: Matthew Horsfall (alh) <wolfsage@gmail.com>
Date: Sun, 15 Jan 2012 14:07:03 -0500
Subject: [PATCH] Warn correctly on defined(%hash = (...))

Traverse down the op tree of OP_AASSIGN to determine the type of the
lhs.
---
 op.c              |   42 +++++++++++++++++++-----------
 t/lib/warnings/op |   72 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 t/op/gv.t         |    5 +++-
 t/op/method.t     |    2 +
 t/op/undef.t      |   12 ++++++--
 t/uni/gv.t        |    5 +++-
 6 files changed, 117 insertions(+), 21 deletions(-)

diff --git a/op.c b/op.c
index d4dcf53..46ee835 100644
--- a/op.c
+++ b/op.c
@@ -8212,26 +8212,36 @@ Perl_ck_defined(pTHX_ OP *o)		/* 19990527 MJD */
 {
     PERL_ARGS_ASSERT_CK_DEFINED;
 
-    if ((o->op_flags & OPf_KIDS)) {
-	switch (cUNOPo->op_first->op_type) {
-	case OP_RV2AV:
-	case OP_PADAV:
-	case OP_AASSIGN:		/* Is this a good idea? */
-	    Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
+    if (ckWARN_d(WARN_DEPRECATED)) {
+	register OP *kid = o->op_flags & OPf_KIDS ? cUNOPo->op_first : NULL;
+
+	if (kid) {
+	    OPCODE type = kid->op_type;
+
+	    /* OP_AASSIGN? Walk the op tree to get what's being assigned to */
+	    if (type == OP_AASSIGN) {
+		type = cUNOPx(cBINOPx(kid)->op_last)->op_first->op_sibling->op_type;
+	    }
+
+	    switch (type) {
+		case OP_RV2AV:
+		case OP_PADAV:
+		    Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
 			   "defined(@array) is deprecated");
-	    Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
+		    Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
 			   "\t(Maybe you should just omit the defined()?)\n");
-	break;
-	case OP_RV2HV:
-	case OP_PADHV:
-	    Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
+		    break;
+		case OP_RV2HV:
+		case OP_PADHV:
+		    Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
 			   "defined(%%hash) is deprecated");
-	    Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
+		    Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
 			   "\t(Maybe you should just omit the defined()?)\n");
-	    break;
-	default:
-	    /* no warning */
-	    break;
+		    break;
+		default:
+		    /* no warning */
+		    break;
+	    }
 	}
     }
     return ck_rfun(o);
diff --git a/t/lib/warnings/op b/t/lib/warnings/op
index 344cf12..33b5a83 100644
--- a/t/lib/warnings/op
+++ b/t/lib/warnings/op
@@ -811,12 +811,48 @@ defined(@array) is deprecated at - line 2.
 	(Maybe you should just omit the defined()?)
 ########
 # op.c
+our @a; defined(@a);
+EXPECT
+defined(@array) is deprecated at - line 2.
+	(Maybe you should just omit the defined()?)
+########
+# op.c
 defined(@a = (1,2,3));
 EXPECT
 defined(@array) is deprecated at - line 2.
 	(Maybe you should just omit the defined()?)
 ########
 # op.c
+defined(my @a);
+EXPECT
+defined(@array) is deprecated at - line 2.
+	(Maybe you should just omit the defined()?)
+########
+# op.c
+defined(our @a);
+EXPECT
+defined(@array) is deprecated at - line 2.
+	(Maybe you should just omit the defined()?)
+########
+# op.c
+my $a = []; defined(@$a);
+EXPECT
+defined(@array) is deprecated at - line 2.
+	(Maybe you should just omit the defined()?)
+########
+# op.c
+my @a; defined(@a = ());
+EXPECT
+defined(@array) is deprecated at - line 2.
+	(Maybe you should just omit the defined()?)
+########
+# op.c
+defined(my @a = ('test', 'test'));
+EXPECT
+defined(@array) is deprecated at - line 2.
+	(Maybe you should just omit the defined()?)
+########
+# op.c
 defined(%h);
 EXPECT
 defined(%hash) is deprecated at - line 2.
@@ -829,6 +865,42 @@ defined(%hash) is deprecated at - line 2.
 	(Maybe you should just omit the defined()?)
 ########
 # op.c
+our %h; defined(%h);
+EXPECT
+defined(%hash) is deprecated at - line 2.
+	(Maybe you should just omit the defined()?)
+########
+# op.c
+defined(my %hash);
+EXPECT
+defined(%hash) is deprecated at - line 2.
+	(Maybe you should just omit the defined()?)
+########
+# op.c
+defined(our %hash);
+EXPECT
+defined(%hash) is deprecated at - line 2.
+	(Maybe you should just omit the defined()?)
+########
+# op.c
+my $hash = {}; defined(%$hash);
+EXPECT
+defined(%hash) is deprecated at - line 2.
+	(Maybe you should just omit the defined()?)
+########
+# op.c
+my %hash; defined(%hash = ());
+EXPECT
+defined(%hash) is deprecated at - line 2.
+	(Maybe you should just omit the defined()?)
+########
+# op.c
+defined(my %hash = ('test' => 'test'));
+EXPECT
+defined(%hash) is deprecated at - line 2.
+	(Maybe you should just omit the defined()?)
+########
+# op.c
 no warnings 'syntax' ;
 exec "$^X -e 1" ; 
 my $a
diff --git a/t/op/gv.t b/t/op/gv.t
index 798cc73..6d88589 100644
--- a/t/op/gv.t
+++ b/t/op/gv.t
@@ -191,8 +191,11 @@ is (*{*x{GLOB}}, "*main::STDOUT");
 
     my $a = "SYM000";
     ok(!defined *{$a});
+    {
+	no warnings 'deprecated';
+	ok(!defined @{$a});
+    }
 
-    ok(!defined @{$a});
     ok(!defined *{$a});
 
     {
diff --git a/t/op/method.t b/t/op/method.t
index d6c81ab..48f0932 100644
--- a/t/op/method.t
+++ b/t/op/method.t
@@ -172,6 +172,8 @@ is(A->eee(), "new B: In A::eee, 4");	# Which sticks
 
 {
     no strict 'refs';
+    no warnings 'deprecated';
+
     # this test added due to bug discovery (in 5.004_04, fb73857aa0bfa8ed)
     is(defined(@{"unknown_package::ISA"}) ? "defined" : "undefined", "undefined");
 }
diff --git a/t/op/undef.t b/t/op/undef.t
index ec8d832..eafa6db 100644
--- a/t/op/undef.t
+++ b/t/op/undef.t
@@ -44,14 +44,17 @@ ok !defined($ary{'bar'});
 undef $ary{'foo'};
 ok !defined($ary{'foo'});
 
-ok defined(@ary);
 {
     no warnings 'deprecated';
+    ok defined(@ary);
     ok defined(%ary);
 }
 ok %ary;
 undef @ary;
-ok !defined(@ary);
+{
+    no warnings 'deprecated';
+    ok !defined(@ary);
+}
 undef %ary;
 {
     no warnings 'deprecated';
@@ -59,7 +62,10 @@ undef %ary;
 }
 ok !%ary;
 @ary = (1);
-ok defined @ary;
+{
+    no warnings 'deprecated';
+    ok defined @ary;
+}
 %ary = (1,1);
 {
     no warnings 'deprecated';
diff --git a/t/uni/gv.t b/t/uni/gv.t
index bd1fee1..f128ec5 100644
--- a/t/uni/gv.t
+++ b/t/uni/gv.t
@@ -194,7 +194,10 @@ is (*{*Ẋ{GLOB}}, "*main::STDOUT");
     my $a = "Sʎm000";
     ok(!defined *{$a});
 
-    ok(!defined @{$a});
+    {
+	no warnings 'deprecated';
+	ok(!defined @{$a});
+    }
     ok(!defined *{$a});
 
     {
-- 
1.7.4.1


Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About