Commit | Line | Data |
---|---|---|
1fa4e549 AD |
1 | #!./perl |
2 | # tests for "goto &sub"-ing into XSUBs | |
3 | ||
1fa4e549 AD |
4 | # Note: This only tests things that should *work*. At some point, it may |
5 | # be worth while to write some failure tests for things that should | |
6 | # *break* (such as calls with wrong number of args). For now, I'm | |
7 | # guessing that if all of these work correctly, the bad ones will | |
8 | # break correctly as well. | |
9 | ||
4210e2f6 NC |
10 | BEGIN { |
11 | chdir 't' if -d 't'; | |
0758e0bf | 12 | require './test.pl'; |
1fa4e549 | 13 | # turn warnings into fatal errors |
4210e2f6 | 14 | $SIG{__WARN__} = sub { die "WARNING: @_" } ; |
1fa4e549 | 15 | |
0758e0bf NC |
16 | skip_all_if_miniperl("no dynamic loading on miniperl, no Fcntl"); |
17 | require Fcntl; | |
4210e2f6 | 18 | } |
0758e0bf NC |
19 | use strict; |
20 | use warnings; | |
21 | use vars '$VALID'; | |
22 | ||
23 | plan(tests => 11); | |
1fa4e549 AD |
24 | |
25 | # We don't know what symbols are defined in platform X's system headers. | |
26 | # We don't even want to guess, because some platform out there will | |
582b1831 NC |
27 | # likely do the unthinkable. However, Fcntl::S_IMODE(0) |
28 | # should always return a value. | |
1fa4e549 | 29 | # If this ceases to be the case, we're in trouble. =) |
582b1831 | 30 | $VALID = 0; |
1fa4e549 | 31 | |
582b1831 NC |
32 | ### First, we check whether Fcntl::S_IMODE returns sane answers. |
33 | # Fcntl::S_IMODE(0) should always succeed. | |
1fa4e549 | 34 | |
0758e0bf NC |
35 | my $value = Fcntl::S_IMODE($VALID); |
36 | isnt($value, undef, 'Sanity check broke, remaining tests will fail'); | |
1fa4e549 AD |
37 | |
38 | ### OK, we're ready to do real tests. | |
39 | ||
582b1831 | 40 | sub goto_const { goto &Fcntl::S_IMODE; } |
1fa4e549 | 41 | |
0758e0bf NC |
42 | my $ret = goto_const($VALID); |
43 | is($ret, $value, 'goto &function_constant'); | |
1fa4e549 | 44 | |
0758e0bf | 45 | my $FNAME1 = 'Fcntl::S_IMODE'; |
1fa4e549 AD |
46 | sub goto_name1 { goto &$FNAME1; } |
47 | ||
59d526a3 | 48 | $ret = goto_name1($VALID); |
0758e0bf | 49 | is($ret, $value, 'goto &$function_package_and_name'); |
1fa4e549 | 50 | |
59d526a3 | 51 | $ret = goto_name1($VALID); |
0758e0bf | 52 | is($ret, $value, 'goto &$function_package_and_name; again, with dirtier stack'); |
59d526a3 | 53 | $ret = goto_name1($VALID); |
0758e0bf | 54 | is($ret, $value, 'goto &$function_package_and_name; again, with dirtier stack'); |
1fa4e549 | 55 | |
0758e0bf | 56 | # test |
1fa4e549 | 57 | package Fcntl; |
0758e0bf | 58 | my $FNAME2 = 'S_IMODE'; |
1fa4e549 AD |
59 | sub goto_name2 { goto &$FNAME2; } |
60 | package main; | |
61 | ||
59d526a3 | 62 | $ret = Fcntl::goto_name2($VALID); |
0758e0bf | 63 | is($ret, $value, 'goto &$function_name; from local package'); |
1fa4e549 | 64 | |
0758e0bf | 65 | my $FREF = \&Fcntl::S_IMODE; |
1fa4e549 AD |
66 | sub goto_ref { goto &$FREF; } |
67 | ||
59d526a3 | 68 | $ret = goto_ref($VALID); |
0758e0bf | 69 | is($ret, $value, 'goto &$function_ref'); |
1fa4e549 AD |
70 | |
71 | ### tests where the args are not on stack but in GvAV(defgv) (ie, @_) | |
72 | ||
1fa4e549 AD |
73 | sub call_goto_const { &goto_const; } |
74 | ||
59d526a3 | 75 | $ret = call_goto_const($VALID); |
0758e0bf | 76 | is($ret, $value, 'goto &function_constant; from a sub called without arglist'); |
1fa4e549 AD |
77 | |
78 | # test "goto &$function_package_and_name" from a sub called without arglist | |
79 | sub call_goto_name1 { &goto_name1; } | |
80 | ||
59d526a3 | 81 | $ret = call_goto_name1($VALID); |
0758e0bf NC |
82 | is($ret, $value, |
83 | 'goto &$function_package_and_name; from a sub called without arglist'); | |
1fa4e549 | 84 | |
1fa4e549 AD |
85 | sub call_goto_ref { &goto_ref; } |
86 | ||
59d526a3 | 87 | $ret = call_goto_ref($VALID); |
0758e0bf | 88 | is($ret, $value, 'goto &$function_ref; from a sub called without arglist'); |
5eff7df7 | 89 | |
5eff7df7 | 90 | |
976bd1ee DM |
91 | BEGIN { |
92 | use Config; | |
93 | if ($Config{extensions} =~ m{XS/APItest}) { | |
94 | eval q[use XS::APItest qw(mycroak); 1] | |
95 | or die "use XS::APItest: $@\n"; | |
96 | } | |
97 | else { | |
98 | *mycroak = sub { die @_ }; | |
99 | } | |
100 | } | |
5eff7df7 DM |
101 | |
102 | sub goto_croak { goto &mycroak } | |
103 | ||
104 | { | |
105 | my $e; | |
106 | for (1..4) { | |
107 | eval { goto_croak("boo$_\n") }; | |
108 | $e .= $@; | |
109 | } | |
0758e0bf NC |
110 | is($e, "boo1\nboo2\nboo3\nboo4\n", |
111 | '[perl #35878] croak in XS after goto segfaulted') | |
5eff7df7 DM |
112 | } |
113 |