This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #93320] localising @DB::args leads to coredump
[perl5.git] / t / op / coreinline.t
CommitLineData
4aaa4757
FC
1#!./perl
2
7fa5bd9b
FC
3# This script tests the inlining of CORE:: subs. Since it’s convenient
4# (this script reads the list in keywords.pl), we also test that prototypes
5# match the built-ins and check for undefinedness.
6
4aaa4757
FC
7BEGIN {
8 chdir 't' if -d 't';
9 @INC = qw(. ../lib);
10 require "test.pl";
11 skip_all_without_dynamic_extension('B');
12 $^P |= 0x100;
13}
14
15use B::Deparse;
6f9f564c 16my $bd = new B::Deparse '-p';
4aaa4757
FC
17
18my %unsupported = map +($_=>1), qw (CORE and cmp dump eq ge gt le
0bbad748 19 lt ne or x xor);
4aaa4757
FC
20my %args_for = (
21 dbmopen => '%1,$2,$3',
22 dbmclose => '%1',
23);
24
25use File::Spec::Functions;
26my $keywords_file = catfile(updir,'regen','keywords.pl');
27open my $kh, $keywords_file
28 or die "$0 cannot open $keywords_file: $!";
29while(<$kh>) {
30 if (m?__END__?..${\0} and /^[+-]/) {
31 chomp(my $word = $');
32 if($& eq '+' || $unsupported{$word}) {
33 $tests ++;
34 ok !defined &{\&{"CORE::$word"}}, "no CORE::$word";
35 }
36 else {
37 $tests += 3;
38
39 my $proto = prototype "CORE::$word";
40 *{"my$word"} = \&{"CORE::$word"};
41 is prototype \&{"my$word"}, $proto, "prototype of &CORE::$word";
42
6f9f564c 43 CORE::state $protochar = qr/([^\\]|\\(?:[^[]|\[[^]]+\]))/;
4aaa4757 44 my $numargs =
6f9f564c 45 () = $proto =~ s/;.*//r =~ /\G$protochar/g;
4aaa4757
FC
46 my $code =
47 "#line 1 This-line-makes-__FILE__-easier-to-test.
48 sub { () = (my$word("
49 . ($args_for{$word} || join ",", map "\$$_", 1..$numargs)
50 . "))}";
51 my $core = $bd->coderef2text(eval $code =~ s/my/CORE::/r or die);
52 my $my = $bd->coderef2text(eval $code or die);
53 is $my, $core, "inlinability of CORE::$word with parens";
54
55 $code =
56 "#line 1 This-line-makes-__FILE__-easier-to-test.
57 sub { () = (my$word "
58 . ($args_for{$word} || join ",", map "\$$_", 1..$numargs)
59 . ")}";
60 $core = $bd->coderef2text(eval $code =~ s/my/CORE::/r or die);
61 $my = $bd->coderef2text(eval $code or die);
62 is $my, $core, "inlinability of CORE::$word without parens";
63
6f9f564c
FC
64 # High-precedence tests
65 my $hpcode;
66 if (!$proto && defined $proto) { # nullary
67 $hpcode = "sub { () = my$word + 1 }";
68 }
69 elsif ($proto =~ /^;?$protochar\z/) { # unary
70 $hpcode = "sub { () = my$word "
71 . ($args_for{$word}||'$a') . ' > $b'
72 .'}';
73 }
74 if ($hpcode) {
75 $tests ++;
76 $core = $bd->coderef2text(eval $hpcode =~ s/my/CORE::/r or die);
77 $my = $bd->coderef2text(eval $hpcode or die);
78 is $my, $core, "precedence of CORE::$word without parens";
79 }
80
4aaa4757
FC
81 next if ($proto =~ /\@/);
82 # These ops currently accept any number of args, despite their
83 # prototypes, if they have any:
0bbad748
FC
84 next if $word =~ /^(?:chom?p|exec|keys|each|not|read(?:lin|pip)e
85 |reset|system|values|l?stat)/x;
4aaa4757
FC
86
87 $tests ++;
88 $code =
89 "sub { () = (my$word("
90 . (
91 $args_for{$word}
92 ? $args_for{$word}.',$7'
93 : join ",", map "\$$_", 1..$numargs+5+(
94 $proto =~ /;/
6f9f564c 95 ? () = $' =~ /\G$protochar/g
4aaa4757
FC
96 : 0
97 )
98 )
99 . "))}";
100 eval $code;
101 like $@, qr/^Too many arguments for $word/,
102 "inlined CORE::$word with too many args"
103 or warn $code;
104
105 }
106 }
107}
108
109is curr_test, $tests+1, 'right number of tests';
110done_testing;
111
112CORE::__END__