Commit | Line | Data |
---|---|---|
87a42246 MS |
1 | #!./perl |
2 | ||
3 | BEGIN { | |
62a6bb71 | 4 | unshift @INC, 't'; |
9cd8f857 NC |
5 | require Config; |
6 | if (($Config::Config{'extensions'} !~ /\bB\b/) ){ | |
7 | print "1..0 # Skip -- Perl configured without B module\n"; | |
8 | exit 0; | |
9 | } | |
87a42246 MS |
10 | } |
11 | ||
87a42246 MS |
12 | use warnings; |
13 | use strict; | |
e9c69003 | 14 | BEGIN { |
c4a6f826 | 15 | # BEGIN block is actually a subroutine :-) |
e9c69003 NC |
16 | return unless $] > 5.009; |
17 | require feature; | |
18 | feature->import(':5.10'); | |
19 | } | |
507a68aa | 20 | use Test::More; |
1bb3cfc5 | 21 | use Config (); |
87a42246 MS |
22 | |
23 | use B::Deparse; | |
09d856fb | 24 | my $deparse = B::Deparse->new(); |
507a68aa | 25 | isa_ok($deparse, 'B::Deparse', 'instantiate a B::Deparse object'); |
87a42246 MS |
26 | |
27 | # Tell B::Deparse about our ambient pragmas | |
0ced6c29 RGS |
28 | { my ($hint_bits, $warning_bits, $hinthash); |
29 | BEGIN { ($hint_bits, $warning_bits, $hinthash) = ($^H, ${^WARNING_BITS}, \%^H); } | |
87a42246 MS |
30 | $deparse->ambient_pragmas ( |
31 | hint_bits => $hint_bits, | |
32 | warning_bits => $warning_bits, | |
0ced6c29 | 33 | '%^H' => $hinthash, |
87a42246 MS |
34 | ); |
35 | } | |
36 | ||
ad46c0be RH |
37 | $/ = "\n####\n"; |
38 | while (<DATA>) { | |
39 | chomp; | |
e9c69003 NC |
40 | # This code is pinched from the t/lib/common.pl for TODO. |
41 | # It's not clear how to avoid duplication | |
b871937f NC |
42 | # Now tweaked a bit to do skip or todo |
43 | my %reason; | |
44 | foreach my $what (qw(skip todo)) { | |
45 | s/^#\s*\U$what\E\s*(.*)\n//m and $reason{$what} = $1; | |
46 | # If the SKIP reason starts ? then it's taken as a code snippet to | |
47 | # evaluate. This provides the flexibility to have conditional SKIPs | |
48 | if ($reason{$what} && $reason{$what} =~ s/^\?//) { | |
49 | my $temp = eval $reason{$what}; | |
50 | if ($@) { | |
51 | die "# In \U$what\E code reason:\n# $reason{$what}\n$@"; | |
52 | } | |
53 | $reason{$what} = $temp; | |
e9c69003 | 54 | } |
e9c69003 NC |
55 | } |
56 | ||
4a4b8592 | 57 | s/^\s*#\s*(.*)$//mg; |
507a68aa NC |
58 | my $desc = $1; |
59 | die "Missing name in test $_" unless defined $desc; | |
e9c69003 | 60 | |
b871937f | 61 | if ($reason{skip}) { |
e9c69003 | 62 | # Like this to avoid needing a label SKIP: |
b871937f | 63 | Test::More->builder->skip($reason{skip}); |
e9c69003 NC |
64 | next; |
65 | } | |
66 | ||
ad46c0be RH |
67 | my ($input, $expected); |
68 | if (/(.*)\n>>>>\n(.*)/s) { | |
69 | ($input, $expected) = ($1, $2); | |
70 | } | |
71 | else { | |
72 | ($input, $expected) = ($_, $_); | |
73 | } | |
87a42246 | 74 | |
ad46c0be | 75 | my $coderef = eval "sub {$input}"; |
87a42246 | 76 | |
ad46c0be | 77 | if ($@) { |
507a68aa | 78 | is($@, "", "compilation of $desc"); |
ad46c0be RH |
79 | } |
80 | else { | |
81 | my $deparsed = $deparse->coderef2text( $coderef ); | |
31c6271a RD |
82 | my $regex = $expected; |
83 | $regex =~ s/(\S+)/\Q$1/g; | |
84 | $regex =~ s/\s+/\\s+/g; | |
85 | $regex = '^\{\s*' . $regex . '\s*\}$'; | |
b871937f | 86 | |
4a4b8592 | 87 | local $::TODO = $reason{todo}; |
507a68aa | 88 | like($deparsed, qr/$regex/, $desc); |
87a42246 | 89 | } |
87a42246 MS |
90 | } |
91 | ||
87a42246 | 92 | use constant 'c', 'stuff'; |
507a68aa NC |
93 | is((eval "sub ".$deparse->coderef2text(\&c))->(), 'stuff', |
94 | 'the subroutine generated by use constant deparses'); | |
87a42246 | 95 | |
09d856fb | 96 | my $a = 0; |
507a68aa NC |
97 | is($deparse->coderef2text(sub{(-1) ** $a }), "{\n (-1) ** \$a;\n}", |
98 | 'anon sub capturing an external lexical'); | |
87a42246 | 99 | |
d989cdac SM |
100 | use constant cr => ['hello']; |
101 | my $string = "sub " . $deparse->coderef2text(\&cr); | |
0707d6cc | 102 | my $val = (eval $string)->() or diag $string; |
507a68aa NC |
103 | is(ref($val), 'ARRAY', 'constant array references deparse'); |
104 | is($val->[0], 'hello', 'and return the correct value'); | |
87a42246 | 105 | |
87a42246 | 106 | my $path = join " ", map { qq["-I$_"] } @INC; |
87a42246 | 107 | |
7cde0a5f | 108 | $a = `$^X $path "-MO=Deparse" -anlwi.bak -e 1 2>&1`; |
e69a2255 | 109 | $a =~ s/-e syntax OK\n//g; |
d2bc402e | 110 | $a =~ s/.*possible typo.*\n//; # Remove warning line |
87a42246 MS |
111 | $a =~ s{\\340\\242}{\\s} if (ord("\\") == 224); # EBCDIC, cp 1047 or 037 |
112 | $a =~ s{\\274\\242}{\\s} if (ord("\\") == 188); # $^O eq 'posix-bc' | |
113 | $b = <<'EOF'; | |
d2bc402e RGS |
114 | BEGIN { $^I = ".bak"; } |
115 | BEGIN { $^W = 1; } | |
116 | BEGIN { $/ = "\n"; $\ = "\n"; } | |
87a42246 MS |
117 | LINE: while (defined($_ = <ARGV>)) { |
118 | chomp $_; | |
f86ea535 | 119 | our(@F) = split(' ', $_, 0); |
87a42246 MS |
120 | '???'; |
121 | } | |
87a42246 | 122 | EOF |
507a68aa NC |
123 | is($a, $b, |
124 | 'command line flags deparse as BEGIN blocks setting control variables'); | |
87a42246 | 125 | |
5b4ee549 NC |
126 | $a = `$^X $path "-MO=Deparse" -e "use constant PI => 4" 2>&1`; |
127 | $a =~ s/-e syntax OK\n//g; | |
128 | is($a, "use constant ('PI', 4);\n", | |
129 | "Proxy Constant Subroutines must not show up as (incorrect) prototypes"); | |
130 | ||
579a54dc | 131 | #Re: perlbug #35857, patch #24505 |
b3980c39 YO |
132 | #handle warnings::register-ed packages properly. |
133 | package B::Deparse::Wrapper; | |
134 | use strict; | |
135 | use warnings; | |
136 | use warnings::register; | |
137 | sub getcode { | |
579a54dc | 138 | my $deparser = B::Deparse->new(); |
b3980c39 YO |
139 | return $deparser->coderef2text(shift); |
140 | } | |
141 | ||
2990415a FR |
142 | package Moo; |
143 | use overload '0+' => sub { 42 }; | |
144 | ||
b3980c39 YO |
145 | package main; |
146 | use strict; | |
147 | use warnings; | |
71c4dbc3 | 148 | use constant GLIPP => 'glipp'; |
2990415a FR |
149 | use constant PI => 4; |
150 | use constant OVERLOADED_NUMIFICATION => bless({}, 'Moo'); | |
3779476a | 151 | use Fcntl qw/O_TRUNC O_APPEND O_EXCL/; |
aaf9c2b2 | 152 | BEGIN { delete $::Fcntl::{O_APPEND}; } |
2990415a | 153 | use POSIX qw/O_CREAT/; |
b3980c39 | 154 | sub test { |
579a54dc RGS |
155 | my $val = shift; |
156 | my $res = B::Deparse::Wrapper::getcode($val); | |
507a68aa NC |
157 | like($res, qr/use warnings/, |
158 | '[perl #35857] [PATCH] B::Deparse doesnt handle warnings register properly'); | |
b3980c39 YO |
159 | } |
160 | my ($q,$p); | |
161 | my $x=sub { ++$q,++$p }; | |
162 | test($x); | |
163 | eval <<EOFCODE and test($x); | |
164 | package bar; | |
165 | use strict; | |
166 | use warnings; | |
167 | use warnings::register; | |
168 | package main; | |
169 | 1 | |
170 | EOFCODE | |
171 | ||
d1dc589d FC |
172 | # Exotic sub declarations |
173 | $a = `$^X $path "-MO=Deparse" -e "sub ::::{}sub ::::::{}" 2>&1`; | |
174 | $a =~ s/-e syntax OK\n//g; | |
175 | is($a, <<'EOCODG', "sub :::: and sub ::::::"); | |
176 | sub :::: { | |
177 | ||
178 | } | |
179 | sub :::::: { | |
180 | ||
181 | } | |
182 | EOCODG | |
183 | ||
640d5d41 FC |
184 | # [perl #33752] |
185 | { | |
186 | my $code = <<"EOCODE"; | |
187 | { | |
188 | our \$\x{1e1f}\x{14d}\x{14d}; | |
189 | } | |
190 | EOCODE | |
191 | my $deparsed | |
192 | = $deparse->coderef2text(eval "sub { our \$\x{1e1f}\x{14d}\x{14d} }" ); | |
193 | s/$ \n//x for $deparsed, $code; | |
194 | is $deparsed, $code, 'our $funny_Unicode_chars'; | |
195 | } | |
196 | ||
bdabb2d5 FC |
197 | # [perl #62500] |
198 | $a = | |
199 | `$^X $path "-MO=Deparse" -e "BEGIN{*CORE::GLOBAL::require=sub{1}}" 2>&1`; | |
200 | $a =~ s/-e syntax OK\n//g; | |
201 | is($a, <<'EOCODF', "CORE::GLOBAL::require override causing panick"); | |
202 | sub BEGIN { | |
203 | *CORE::GLOBAL::require = sub { | |
204 | 1; | |
205 | } | |
206 | ; | |
207 | } | |
208 | EOCODF | |
209 | ||
bb8996b8 | 210 | # [perl #93990] |
5c19ffe6 | 211 | @* = (); |
bb8996b8 HY |
212 | is($deparse->coderef2text(sub{ print "@{*}" }), |
213 | q<{ | |
214 | print "@{*}"; | |
215 | }>, 'curly around to interpolate "@{*}"'); | |
216 | is($deparse->coderef2text(sub{ print "@{-}" }), | |
217 | q<{ | |
218 | print "@-"; | |
219 | }>, 'no need to curly around to interpolate "@-"'); | |
220 | ||
507a68aa NC |
221 | done_testing(); |
222 | ||
ad46c0be | 223 | __DATA__ |
507a68aa | 224 | # A constant |
ad46c0be RH |
225 | 1; |
226 | #### | |
507a68aa | 227 | # Constants in a block |
ad46c0be RH |
228 | { |
229 | no warnings; | |
230 | '???'; | |
231 | 2; | |
232 | } | |
233 | #### | |
507a68aa | 234 | # Lexical and simple arithmetic |
ad46c0be RH |
235 | my $test; |
236 | ++$test and $test /= 2; | |
237 | >>>> | |
238 | my $test; | |
239 | $test /= 2 if ++$test; | |
240 | #### | |
507a68aa | 241 | # list x |
ad46c0be RH |
242 | -((1, 2) x 2); |
243 | #### | |
507a68aa | 244 | # lvalue sub |
ad46c0be RH |
245 | { |
246 | my $test = sub : lvalue { | |
247 | my $x; | |
248 | } | |
249 | ; | |
250 | } | |
251 | #### | |
507a68aa | 252 | # method |
ad46c0be RH |
253 | { |
254 | my $test = sub : method { | |
255 | my $x; | |
256 | } | |
257 | ; | |
258 | } | |
259 | #### | |
507a68aa | 260 | # block with continue |
87a42246 | 261 | { |
ad46c0be | 262 | 234; |
f99a63a2 | 263 | } |
ad46c0be RH |
264 | continue { |
265 | 123; | |
87a42246 | 266 | } |
ce4e655d | 267 | #### |
507a68aa | 268 | # lexical and package scalars |
ce4e655d RH |
269 | my $x; |
270 | print $main::x; | |
271 | #### | |
507a68aa | 272 | # lexical and package arrays |
ce4e655d RH |
273 | my @x; |
274 | print $main::x[1]; | |
14a55f98 | 275 | #### |
507a68aa | 276 | # lexical and package hashes |
14a55f98 RH |
277 | my %x; |
278 | $x{warn()}; | |
ad8caead | 279 | #### |
507a68aa | 280 | # <> |
ad8caead RGS |
281 | my $foo; |
282 | $_ .= <ARGV> . <$foo>; | |
cef22867 | 283 | #### |
507a68aa | 284 | # \x{} |
11454c59 | 285 | my $foo = "Ab\x{100}\200\x{200}\237Cd\000Ef\x{1000}\cA\x{2000}\cZ"; |
4ae52e81 | 286 | #### |
507a68aa | 287 | # s///e |
4ae52e81 | 288 | s/x/'y';/e; |
241416b8 | 289 | #### |
507a68aa | 290 | # block |
241416b8 DM |
291 | { my $x; } |
292 | #### | |
507a68aa | 293 | # while 1 |
241416b8 DM |
294 | while (1) { my $k; } |
295 | #### | |
507a68aa | 296 | # trailing for |
241416b8 DM |
297 | my ($x,@a); |
298 | $x=1 for @a; | |
299 | >>>> | |
300 | my($x, @a); | |
0bb5f065 | 301 | $x = 1 foreach (@a); |
241416b8 | 302 | #### |
507a68aa | 303 | # 2 arguments in a 3 argument for |
241416b8 DM |
304 | for (my $i = 0; $i < 2;) { |
305 | my $z = 1; | |
306 | } | |
307 | #### | |
507a68aa | 308 | # 3 argument for |
241416b8 DM |
309 | for (my $i = 0; $i < 2; ++$i) { |
310 | my $z = 1; | |
311 | } | |
312 | #### | |
507a68aa | 313 | # 3 argument for again |
241416b8 DM |
314 | for (my $i = 0; $i < 2; ++$i) { |
315 | my $z = 1; | |
316 | } | |
317 | #### | |
507a68aa | 318 | # while/continue |
241416b8 DM |
319 | my $i; |
320 | while ($i) { my $z = 1; } continue { $i = 99; } | |
321 | #### | |
507a68aa | 322 | # foreach with my |
09d856fb | 323 | foreach my $i (1, 2) { |
241416b8 DM |
324 | my $z = 1; |
325 | } | |
326 | #### | |
507a68aa | 327 | # foreach |
241416b8 DM |
328 | my $i; |
329 | foreach $i (1, 2) { | |
330 | my $z = 1; | |
331 | } | |
332 | #### | |
507a68aa | 333 | # foreach, 2 mys |
241416b8 DM |
334 | my $i; |
335 | foreach my $i (1, 2) { | |
336 | my $z = 1; | |
337 | } | |
338 | #### | |
507a68aa | 339 | # foreach |
241416b8 DM |
340 | foreach my $i (1, 2) { |
341 | my $z = 1; | |
342 | } | |
343 | #### | |
507a68aa | 344 | # foreach with our |
241416b8 DM |
345 | foreach our $i (1, 2) { |
346 | my $z = 1; | |
347 | } | |
348 | #### | |
507a68aa | 349 | # foreach with my and our |
241416b8 DM |
350 | my $i; |
351 | foreach our $i (1, 2) { | |
352 | my $z = 1; | |
353 | } | |
3ac6e0f9 | 354 | #### |
507a68aa | 355 | # reverse sort |
3ac6e0f9 RGS |
356 | my @x; |
357 | print reverse sort(@x); | |
358 | #### | |
507a68aa | 359 | # sort with cmp |
3ac6e0f9 RGS |
360 | my @x; |
361 | print((sort {$b cmp $a} @x)); | |
362 | #### | |
507a68aa | 363 | # reverse sort with block |
3ac6e0f9 RGS |
364 | my @x; |
365 | print((reverse sort {$b <=> $a} @x)); | |
36d57d93 | 366 | #### |
507a68aa | 367 | # foreach reverse |
36d57d93 RGS |
368 | our @a; |
369 | print $_ foreach (reverse @a); | |
aae53c41 | 370 | #### |
507a68aa | 371 | # foreach reverse (not inplace) |
aae53c41 RGS |
372 | our @a; |
373 | print $_ foreach (reverse 1, 2..5); | |
f86ea535 | 374 | #### |
507a68aa | 375 | # bug #38684 |
f86ea535 SM |
376 | our @ary; |
377 | @ary = split(' ', 'foo', 0); | |
31c6271a | 378 | #### |
507a68aa | 379 | # bug #40055 |
31c6271a RD |
380 | do { () }; |
381 | #### | |
507a68aa | 382 | # bug #40055 |
31c6271a | 383 | do { my $x = 1; $x }; |
d9002312 | 384 | #### |
507a68aa | 385 | # <20061012113037.GJ25805@c4.convolution.nl> |
d9002312 SM |
386 | my $f = sub { |
387 | +{[]}; | |
388 | } ; | |
8b2d6640 | 389 | #### |
507a68aa | 390 | # bug #43010 |
8b2d6640 FC |
391 | '!@$%'->(); |
392 | #### | |
507a68aa | 393 | # bug #43010 |
8b2d6640 FC |
394 | ::(); |
395 | #### | |
507a68aa | 396 | # bug #43010 |
8b2d6640 FC |
397 | '::::'->(); |
398 | #### | |
507a68aa | 399 | # bug #43010 |
8b2d6640 | 400 | &::::; |
09d856fb | 401 | #### |
1b38d782 FC |
402 | # [perl #77172] |
403 | package rt77172; | |
404 | sub foo {} foo & & & foo; | |
405 | >>>> | |
406 | package rt77172; | |
407 | foo(&{&} & foo()); | |
408 | #### | |
507a68aa | 409 | # variables as method names |
09d856fb CK |
410 | my $bar; |
411 | 'Foo'->$bar('orz'); | |
35a99a08 | 412 | 'Foo'->$bar('orz') = 'a stranger stranger than before'; |
09d856fb | 413 | #### |
507a68aa | 414 | # constants as method names |
09d856fb CK |
415 | 'Foo'->bar('orz'); |
416 | #### | |
507a68aa | 417 | # constants as method names without () |
09d856fb | 418 | 'Foo'->bar; |
0ced6c29 | 419 | #### |
28bfcb02 | 420 | # [perl #47359] "indirect" method call notation |
1bf8bbb0 FC |
421 | our @bar; |
422 | foo{@bar}+1,->foo; | |
423 | (foo{@bar}+1),foo(); | |
424 | foo{@bar}1 xor foo(); | |
425 | >>>> | |
426 | our @bar; | |
427 | (foo { @bar } 1)->foo; | |
428 | (foo { @bar } 1), foo(); | |
429 | foo { @bar } 1 xor foo(); | |
430 | #### | |
e9c69003 | 431 | # SKIP ?$] < 5.010 && "say not implemented on this Perl version" |
507a68aa | 432 | # say |
7ddd1a01 NC |
433 | say 'foo'; |
434 | #### | |
e9c69003 | 435 | # SKIP ?$] < 5.010 && "state vars not implemented on this Perl version" |
507a68aa | 436 | # state vars |
0ced6c29 RGS |
437 | state $x = 42; |
438 | #### | |
e9c69003 | 439 | # SKIP ?$] < 5.010 && "state vars not implemented on this Perl version" |
507a68aa | 440 | # state var assignment |
7ddd1a01 NC |
441 | { |
442 | my $y = (state $x = 42); | |
443 | } | |
444 | #### | |
e9c69003 | 445 | # SKIP ?$] < 5.010 && "state vars not implemented on this Perl version" |
c4a6f826 | 446 | # state vars in anonymous subroutines |
7ddd1a01 NC |
447 | $a = sub { |
448 | state $x; | |
449 | return $x++; | |
450 | } | |
451 | ; | |
644741fd NC |
452 | #### |
453 | # SKIP ?$] < 5.011 && 'each @array not implemented on this Perl version' | |
507a68aa | 454 | # each @array; |
644741fd NC |
455 | each @ARGV; |
456 | each @$a; | |
457 | #### | |
458 | # SKIP ?$] < 5.011 && 'each @array not implemented on this Perl version' | |
507a68aa | 459 | # keys @array; values @array |
644741fd NC |
460 | keys @$a if keys @ARGV; |
461 | values @ARGV if values @$a; | |
35925e80 | 462 | #### |
507a68aa | 463 | # Anonymous arrays and hashes, and references to them |
35925e80 RGS |
464 | my $a = {}; |
465 | my $b = \{}; | |
466 | my $c = []; | |
467 | my $d = \[]; | |
9210de83 FR |
468 | #### |
469 | # SKIP ?$] < 5.010 && "smartmatch and given/when not implemented on this Perl version" | |
507a68aa | 470 | # implicit smartmatch in given/when |
9210de83 FR |
471 | given ('foo') { |
472 | when ('bar') { continue; } | |
473 | when ($_ ~~ 'quux') { continue; } | |
474 | default { 0; } | |
475 | } | |
7ecdd211 | 476 | #### |
507a68aa | 477 | # conditions in elsifs (regression in change #33710 which fixed bug #37302) |
7ecdd211 PJ |
478 | if ($a) { x(); } |
479 | elsif ($b) { x(); } | |
480 | elsif ($a and $b) { x(); } | |
481 | elsif ($a or $b) { x(); } | |
482 | else { x(); } | |
03b22f1b | 483 | #### |
507a68aa | 484 | # interpolation in regexps |
03b22f1b RGS |
485 | my($y, $t); |
486 | /x${y}z$t/; | |
227375e1 | 487 | #### |
4a4b8592 | 488 | # TODO new undocumented cpan-bug #33708 |
507a68aa | 489 | # cpan-bug #33708 |
227375e1 RU |
490 | %{$_ || {}} |
491 | #### | |
4a4b8592 | 492 | # TODO hash constants not yet fixed |
507a68aa | 493 | # cpan-bug #33708 |
227375e1 RU |
494 | use constant H => { "#" => 1 }; H->{"#"} |
495 | #### | |
4a4b8592 | 496 | # TODO optimized away 0 not yet fixed |
507a68aa | 497 | # cpan-bug #33708 |
227375e1 | 498 | foreach my $i (@_) { 0 } |
edbe35ea | 499 | #### |
507a68aa | 500 | # tests with not, not optimized |
07f3cdf5 | 501 | my $c; |
edbe35ea VP |
502 | x() unless $a; |
503 | x() if not $a and $b; | |
504 | x() if $a and not $b; | |
505 | x() unless not $a and $b; | |
506 | x() unless $a and not $b; | |
507 | x() if not $a or $b; | |
508 | x() if $a or not $b; | |
509 | x() unless not $a or $b; | |
510 | x() unless $a or not $b; | |
07f3cdf5 VP |
511 | x() if $a and not $b and $c; |
512 | x() if not $a and $b and not $c; | |
513 | x() unless $a and not $b and $c; | |
514 | x() unless not $a and $b and not $c; | |
515 | x() if $a or not $b or $c; | |
516 | x() if not $a or $b or not $c; | |
517 | x() unless $a or not $b or $c; | |
518 | x() unless not $a or $b or not $c; | |
edbe35ea | 519 | #### |
507a68aa | 520 | # tests with not, optimized |
07f3cdf5 | 521 | my $c; |
edbe35ea VP |
522 | x() if not $a; |
523 | x() unless not $a; | |
524 | x() if not $a and not $b; | |
525 | x() unless not $a and not $b; | |
526 | x() if not $a or not $b; | |
527 | x() unless not $a or not $b; | |
07f3cdf5 VP |
528 | x() if not $a and not $b and $c; |
529 | x() unless not $a and not $b and $c; | |
530 | x() if not $a or not $b or $c; | |
531 | x() unless not $a or not $b or $c; | |
532 | x() if not $a and not $b and not $c; | |
533 | x() unless not $a and not $b and not $c; | |
534 | x() if not $a or not $b or not $c; | |
535 | x() unless not $a or not $b or not $c; | |
536 | x() unless not $a or not $b or not $c; | |
edbe35ea | 537 | >>>> |
07f3cdf5 | 538 | my $c; |
edbe35ea VP |
539 | x() unless $a; |
540 | x() if $a; | |
541 | x() unless $a or $b; | |
542 | x() if $a or $b; | |
543 | x() unless $a and $b; | |
07f3cdf5 VP |
544 | x() if $a and $b; |
545 | x() if not $a || $b and $c; | |
546 | x() unless not $a || $b and $c; | |
547 | x() if not $a && $b or $c; | |
548 | x() unless not $a && $b or $c; | |
549 | x() unless $a or $b or $c; | |
550 | x() if $a or $b or $c; | |
551 | x() unless $a and $b and $c; | |
552 | x() if $a and $b and $c; | |
553 | x() unless not $a && $b && $c; | |
71c4dbc3 | 554 | #### |
507a68aa | 555 | # tests that should be constant folded |
71c4dbc3 VP |
556 | x() if 1; |
557 | x() if GLIPP; | |
558 | x() if !GLIPP; | |
559 | x() if GLIPP && GLIPP; | |
560 | x() if !GLIPP || GLIPP; | |
561 | x() if do { GLIPP }; | |
562 | x() if do { no warnings 'void'; 5; GLIPP }; | |
563 | x() if do { !GLIPP }; | |
564 | if (GLIPP) { x() } else { z() } | |
565 | if (!GLIPP) { x() } else { z() } | |
566 | if (GLIPP) { x() } elsif (GLIPP) { z() } | |
567 | if (!GLIPP) { x() } elsif (GLIPP) { z() } | |
568 | if (GLIPP) { x() } elsif (!GLIPP) { z() } | |
569 | if (!GLIPP) { x() } elsif (!GLIPP) { z() } | |
570 | if (!GLIPP) { x() } elsif (!GLIPP) { z() } elsif (GLIPP) { t() } | |
571 | if (!GLIPP) { x() } elsif (!GLIPP) { z() } elsif (!GLIPP) { t() } | |
572 | if (!GLIPP) { x() } elsif (!GLIPP) { z() } elsif (!GLIPP) { t() } | |
573 | >>>> | |
574 | x(); | |
575 | x(); | |
576 | '???'; | |
577 | x(); | |
578 | x(); | |
579 | x(); | |
580 | x(); | |
581 | do { | |
582 | '???' | |
583 | }; | |
584 | do { | |
585 | x() | |
586 | }; | |
587 | do { | |
588 | z() | |
589 | }; | |
590 | do { | |
591 | x() | |
592 | }; | |
593 | do { | |
594 | z() | |
595 | }; | |
596 | do { | |
597 | x() | |
598 | }; | |
599 | '???'; | |
600 | do { | |
601 | t() | |
602 | }; | |
603 | '???'; | |
604 | !1; | |
605 | #### | |
719c50dc RGS |
606 | # TODO constant deparsing has been backed out for 5.12 |
607 | # XXXTODO ? $Config::Config{useithreads} && "doesn't work with threads" | |
507a68aa | 608 | # tests that shouldn't be constant folded |
ac0f1413 NC |
609 | # It might be fundamentally impossible to make this work on ithreads, in which |
610 | # case the TODO should become a SKIP | |
71c4dbc3 VP |
611 | x() if $a; |
612 | if ($a == 1) { x() } elsif ($b == 2) { z() } | |
613 | if (do { foo(); GLIPP }) { x() } | |
614 | if (do { $a++; GLIPP }) { x() } | |
615 | >>>> | |
616 | x() if $a; | |
617 | if ($a == 1) { x(); } elsif ($b == 2) { z(); } | |
2990415a FR |
618 | if (do { foo(); GLIPP }) { x(); } |
619 | if (do { ++$a; GLIPP }) { x(); } | |
620 | #### | |
0fa4a265 | 621 | # TODO constant deparsing has been backed out for 5.12 |
507a68aa | 622 | # tests for deparsing constants |
2990415a FR |
623 | warn PI; |
624 | #### | |
0fa4a265 | 625 | # TODO constant deparsing has been backed out for 5.12 |
507a68aa | 626 | # tests for deparsing imported constants |
3779476a | 627 | warn O_TRUNC; |
2990415a | 628 | #### |
0fa4a265 | 629 | # TODO constant deparsing has been backed out for 5.12 |
507a68aa | 630 | # tests for deparsing re-exported constants |
2990415a FR |
631 | warn O_CREAT; |
632 | #### | |
0fa4a265 | 633 | # TODO constant deparsing has been backed out for 5.12 |
507a68aa | 634 | # tests for deparsing imported constants that got deleted from the original namespace |
aaf9c2b2 | 635 | warn O_APPEND; |
2990415a | 636 | #### |
0fa4a265 DM |
637 | # TODO constant deparsing has been backed out for 5.12 |
638 | # XXXTODO ? $Config::Config{useithreads} && "doesn't work with threads" | |
507a68aa | 639 | # tests for deparsing constants which got turned into full typeglobs |
ac0f1413 NC |
640 | # It might be fundamentally impossible to make this work on ithreads, in which |
641 | # case the TODO should become a SKIP | |
2990415a FR |
642 | warn O_EXCL; |
643 | eval '@Fcntl::O_EXCL = qw/affe tiger/;'; | |
644 | warn O_EXCL; | |
645 | #### | |
0fa4a265 | 646 | # TODO constant deparsing has been backed out for 5.12 |
507a68aa | 647 | # tests for deparsing of blessed constant with overloaded numification |
2990415a | 648 | warn OVERLOADED_NUMIFICATION; |
79289e05 NC |
649 | #### |
650 | # TODO Only strict 'refs' currently supported | |
507a68aa | 651 | # strict |
79289e05 NC |
652 | no strict; |
653 | $x; | |
654 | #### | |
655 | # TODO Subsets of warnings could be encoded textually, rather than as bitflips. | |
507a68aa | 656 | # subsets of warnings |
79289e05 NC |
657 | no warnings 'deprecated'; |
658 | my $x; | |
659 | #### | |
660 | # TODO Better test for CPAN #33708 - the deparsed code has different behaviour | |
507a68aa | 661 | # CPAN #33708 |
79289e05 NC |
662 | use strict; |
663 | no warnings; | |
664 | ||
665 | foreach (0..3) { | |
666 | my $x = 2; | |
667 | { | |
668 | my $x if 0; | |
669 | print ++$x, "\n"; | |
670 | } | |
671 | } | |
d83f38d8 | 672 | #### |
507a68aa | 673 | # no attribute list |
d83f38d8 NC |
674 | my $pi = 4; |
675 | #### | |
2dc78664 NC |
676 | # SKIP ?$] > 5.013006 && ":= is now a syntax error" |
677 | # := treated as an empty attribute list | |
d83f38d8 NC |
678 | no warnings; |
679 | my $pi := 4; | |
680 | >>>> | |
681 | no warnings; | |
682 | my $pi = 4; | |
683 | #### | |
507a68aa | 684 | # : = empty attribute list |
d83f38d8 NC |
685 | my $pi : = 4; |
686 | >>>> | |
687 | my $pi = 4; | |
689e417f | 688 | #### |
507a68aa | 689 | # in place sort |
689e417f VP |
690 | our @a; |
691 | my @b; | |
692 | @a = sort @a; | |
693 | @b = sort @b; | |
694 | (); | |
695 | #### | |
507a68aa | 696 | # in place reverse |
689e417f VP |
697 | our @a; |
698 | my @b; | |
699 | @a = reverse @a; | |
700 | @b = reverse @b; | |
701 | (); | |
06fc6867 | 702 | #### |
507a68aa | 703 | # #71870 Use of uninitialized value in bitwise and B::Deparse |
06fc6867 VP |
704 | my($r, $s, @a); |
705 | @a = split(/foo/, $s, 0); | |
706 | $r = qr/foo/; | |
707 | @a = split(/$r/, $s, 0); | |
708 | (); | |
98a1a137 | 709 | #### |
507a68aa | 710 | # package declaration before label |
98a1a137 Z |
711 | { |
712 | package Foo; | |
713 | label: print 123; | |
714 | } | |
538f5756 | 715 | #### |
507a68aa | 716 | # shift optimisation |
538f5756 RZ |
717 | shift; |
718 | >>>> | |
719 | shift(); | |
720 | #### | |
507a68aa | 721 | # shift optimisation |
538f5756 RZ |
722 | shift @_; |
723 | #### | |
507a68aa | 724 | # shift optimisation |
538f5756 RZ |
725 | pop; |
726 | >>>> | |
727 | pop(); | |
728 | #### | |
507a68aa | 729 | # shift optimisation |
538f5756 | 730 | pop @_; |
a539498a | 731 | #### |
507a68aa | 732 | #[perl #20444] |
a539498a FC |
733 | "foo" =~ (1 ? /foo/ : /bar/); |
734 | "foo" =~ (1 ? y/foo// : /bar/); | |
5e5a1632 | 735 | "foo" =~ (1 ? y/foo//r : /bar/); |
a539498a FC |
736 | "foo" =~ (1 ? s/foo// : /bar/); |
737 | >>>> | |
738 | 'foo' =~ ($_ =~ /foo/); | |
739 | 'foo' =~ ($_ =~ tr/fo//); | |
5e5a1632 | 740 | 'foo' =~ ($_ =~ tr/fo//r); |
a539498a | 741 | 'foo' =~ ($_ =~ s/foo//); |
e0ab66ad | 742 | #### |
5e5a1632 FC |
743 | # The fix for [perl #20444] broke this. |
744 | 'foo' =~ do { () }; | |
745 | #### | |
e0ab66ad NC |
746 | # Test @threadsv_names under 5005threads |
747 | foreach $' (1, 2) { | |
748 | sleep $'; | |
749 | } | |
e7afc405 FC |
750 | #### |
751 | # y///r | |
752 | tr/a/b/r; | |
cb8157e3 FC |
753 | #### |
754 | # y/uni/code/ | |
755 | tr/\x{345}/\x{370}/; | |
cb8578ff FC |
756 | #### |
757 | # [perl #90898] | |
f4002a4b | 758 | <a,>; |
09dcfa7d FC |
759 | #### |
760 | # [perl #91008] | |
761 | each $@; | |
762 | keys $~; | |
763 | values $!; | |
5d8c42c2 FC |
764 | #### |
765 | # readpipe with complex expression | |
766 | readpipe $a + $b; | |
93bad3fd NC |
767 | #### |
768 | # aelemfast | |
769 | $b::a[0] = 1; | |
770 | #### | |
771 | # aelemfast for a lexical | |
772 | my @a; | |
773 | $a[0] = 1; | |
80e3f4ad FC |
774 | #### |
775 | # feature features without feature | |
776 | BEGIN { | |
777 | delete $^H{'feature_say'}; | |
778 | delete $^H{'feature_state'}; | |
779 | delete $^H{'feature_switch'}; | |
780 | } | |
781 | CORE::state $x; | |
782 | CORE::say $x; | |
783 | CORE::given ($x) { | |
784 | CORE::when (3) { | |
785 | continue; | |
786 | } | |
787 | CORE::default { | |
e36901c8 | 788 | CORE::break; |
80e3f4ad FC |
789 | } |
790 | } | |
7d789282 | 791 | CORE::evalbytes ''; |
84ed0108 | 792 | () = CORE::__SUB__; |
6ec73527 FC |
793 | #### |
794 | # $#- $#+ $#{%} etc. | |
795 | my @x; | |
796 | @x = ($#{`}, $#{~}, $#{!}, $#{@}, $#{$}, $#{%}, $#{^}, $#{&}, $#{*}); | |
797 | @x = ($#{(}, $#{)}, $#{[}, $#{{}, $#{]}, $#{}}, $#{'}, $#{"}, $#{,}); | |
798 | @x = ($#{<}, $#{.}, $#{>}, $#{/}, $#{?}, $#{=}, $#+, $#{\}, $#{|}, $#-); | |
799 | @x = ($#{;}, $#{:}); | |
61154ac0 FC |
800 | #### |
801 | # ${#} interpolated (the first line magically disables the warning) | |
802 | () = *#; | |
803 | () = "${#}a"; | |
958ed56b FC |
804 | #### |
805 | # ()[...] | |
806 | my(@a) = ()[()]; | |
521795fe FC |
807 | #### |
808 | # sort(foo(bar)) | |
809 | # sort(foo(bar)) is interpreted as sort &foo(bar) | |
810 | # sort foo(bar) is interpreted as sort foo bar | |
811 | # parentheses are not optional in this case | |
812 | print sort(foo('bar')); | |
813 | >>>> | |
814 | print sort(foo('bar')); | |
24fcb59f FC |
815 | #### |
816 | # substr assignment | |
817 | substr(my $a, 0, 0) = (foo(), bar()); | |
818 | $a++; | |
04be0204 FC |
819 | #### |
820 | # hint hash | |
821 | BEGIN { $^H{'foo'} = undef; } | |
822 | { | |
823 | BEGIN { $^H{'bar'} = undef; } | |
824 | { | |
825 | BEGIN { $^H{'baz'} = undef; } | |
826 | { | |
827 | print $_; | |
828 | } | |
829 | print $_; | |
830 | } | |
831 | print $_; | |
832 | } | |
035146a3 FC |
833 | BEGIN { $^H{q[']} = '('; } |
834 | print $_; | |
c306e834 FC |
835 | #### |
836 | # hint hash changes that serialise the same way with sort %hh | |
837 | BEGIN { $^H{'a'} = 'b'; } | |
838 | { | |
839 | BEGIN { $^H{'b'} = 'a'; delete $^H{'a'}; } | |
840 | print $_; | |
841 | } | |
842 | print $_; | |
94bb57f9 FC |
843 | #### |
844 | # [perl #47361] do({}) and do +{} (variants of do-file) | |
845 | do({}); | |
846 | do +{}; | |
8b46c09b FC |
847 | sub foo::do {} |
848 | package foo; | |
849 | CORE::do({}); | |
850 | CORE::do +{}; | |
94bb57f9 FC |
851 | >>>> |
852 | do({}); | |
853 | do({}); | |
8b46c09b FC |
854 | package foo; |
855 | CORE::do({}); | |
856 | CORE::do({}); | |
9c56d9ea FC |
857 | #### |
858 | # [perl #77096] functions that do not follow the llafr | |
859 | () = (return 1) + time; | |
860 | () = (return ($1 + $2) * $3) + time; | |
861 | () = (return ($a xor $b)) + time; | |
862 | () = (do 'file') + time; | |
863 | () = (do ($1 + $2) * $3) + time; | |
864 | () = (do ($1 xor $2)) + time; | |
41df74e3 FC |
865 | () = (goto 1) + 3; |
866 | () = (require 'foo') + 3; | |
867 | () = (require foo) + 3; | |
266da325 | 868 | () = (CORE::dump 1) + 3; |
41df74e3 FC |
869 | () = (last 1) + 3; |
870 | () = (next 1) + 3; | |
871 | () = (redo 1) + 3; | |
5830412d FC |
872 | () = (-R $_) + 3; |
873 | () = (-W $_) + 3; | |
874 | () = (-X $_) + 3; | |
875 | () = (-r $_) + 3; | |
876 | () = (-w $_) + 3; | |
877 | () = (-x $_) + 3; | |
2462c3cc | 878 | #### |
1cabb3b3 FC |
879 | # [perl #97476] not() *does* follow the llafr |
880 | $_ = ($a xor not +($1 || 2) ** 2); | |
881 | #### | |
4d8ac5c7 FC |
882 | # Precedence conundrums with argument-less function calls |
883 | () = (eof) + 1; | |
884 | () = (return) + 1; | |
885 | () = (return, 1); | |
7bc8c979 FC |
886 | () = warn; |
887 | () = warn() + 1; | |
4d8ac5c7 FC |
888 | () = setpgrp() + 1; |
889 | #### | |
2462c3cc FC |
890 | # [perl #63558] open local(*FH) |
891 | open local *FH; | |
564cd6cb | 892 | pipe local *FH, local *FH; |
843b15cc FC |
893 | #### |
894 | # [perl #74740] -(f()) vs -f() | |
895 | $_ = -(f()); | |
c75b4828 FC |
896 | #### |
897 | # require <binop> | |
898 | require 'a' . $1; |