case KEY_keys:
case KEY_lstat:
case KEY_pop:
- case KEY_push: case KEY_read:
- case KEY_recv: case KEY_reset:
+ case KEY_push: case KEY_reset:
case KEY_select: case KEY_send:
case KEY_setpgrp: case KEY_shift: case KEY_sleep:
case KEY_splice:
case KEY_srand: case KEY_stat: case KEY_substr:
- case KEY_sysopen: case KEY_sysread:
+ case KEY_sysopen:
case KEY_system: case KEY_syswrite:
case KEY_tell: case KEY_tie: case KEY_tied:
case KEY_truncate: case KEY_umask: case KEY_unlink:
}
break;
case OA_SCALARREF:
+ {
+ const bool wantscalar =
+ PL_op->op_private & OPpCOREARGS_SCALARMOD;
if (!svp || !*svp || !SvROK(*svp)
- || SvTYPE(SvRV(*svp)) > SVt_PVCV
+ /* We have to permit globrefs even for the \$ proto, as
+ *foo is indistinguishable from ${\*foo}, and the proto-
+ type permits the latter. */
+ || SvTYPE(SvRV(*svp)) > (
+ wantscalar ? SVt_PVLV : SVt_PVCV
+ )
)
DIE(aTHX_
/* diag_listed_as: Type of arg %d to &CORE::%s must be %s*/
- "Type of arg %d to &CORE::%s must be reference to one of "
- "[$@%%&*]",
- whicharg, OP_DESC(PL_op->op_next)
+ "Type of arg %d to &CORE::%s must be %s",
+ whicharg, OP_DESC(PL_op->op_next),
+ wantscalar
+ ? "scalar reference"
+ : "reference to one of [$@%&*]"
);
PUSHs(SvRV(*svp));
break;
+ }
default:
DIE(aTHX_ "panic: unknown OA_*: %x", (unsigned)(oa&7));
}
&is(map(@$_ ? "[@{[map $_//'~~u~~', @$_]}]" : 'nought', @_[0,1]), $_[2]);
}
+package hov {
+ use overload '%{}' => sub { +{} }
+}
+package sov {
+ use overload '${}' => sub { \my $x }
+}
+
my %op_desc = (
join => 'join or string',
readline => '<HANDLE>',
like $@, qr/^Not enough arguments for $desc at /,
"&$o with too few args";
}
+ elsif ($p =~ /^\*\\\$\$(;?)\$\z/) { # *\$$$ and *\$$;$
+ $tests += 5;
+
+ eval "&CORE::$o(1,1,1,1,1)";
+ like $@, qr/^Too many arguments for $o at /,
+ "&$o with too many args";
+ eval " &CORE::$o((1)x(\$1?2:3)) ";
+ like $@, qr/^Not enough arguments for $o at /,
+ "&$o with too few args";
+ eval " &CORE::$o(1,[],1,1) ";
+ like $@, qr/^Type of arg 2 to &CORE::$o must be scalar reference at /,
+ "&$o with array ref arg";
+ eval " &CORE::$o(1,1,1,1) ";
+ like $@, qr/^Type of arg 2 to &CORE::$o must be scalar reference at /,
+ "&$o with scalar arg";
+ eval " &CORE::$o(1,bless([], 'sov'),1,1) ";
+ like $@, qr/^Type of arg 2 to &CORE::$o must be scalar reference at /,
+ "&$o with non-scalar arg w/scalar overload (which does not count)";
+ }
elsif ($p =~ /^\\%\$*\z/) { # \% and \%$$
$tests += 5;
unlike join(" ", &CORE::rand), qr/ /, '&rand in list context';
&cmp_ok(&CORE::rand(78), qw '< 78', '&rand with 2 args');
+test_proto 'read';
+{
+ last if is_miniperl;
+ $tests += 5;
+ open my $fh, "<", \(my $buff = 'morays have their mores');
+ ok &myread($fh, \my $input, 6), '&read with 3 args';
+ is $input, 'morays', 'value read by 3-arg &read';
+ ok &myread($fh, \$input, 6, 6), '&read with 4 args';
+ is $input, 'morays have ', 'value read by 4-arg &read';
+ is +()=&myread($fh, \$input, 6), 1, '&read in list context';
+}
+
test_proto 'readdir';
test_proto 'readline';
test_proto 'readlink';
test_proto 'readpipe';
+test_proto 'recv';
use if !is_miniperl, File::Spec::Functions, qw "catfile";
use if !is_miniperl, File::Temp, 'tempdir';
test_proto 'sqrt', 4, 2;
test_proto 'symlink';
test_proto 'syscall';
+test_proto 'sysread';
test_proto 'sysseek';
test_proto 'telldir';