Skip to content

Is "Modification of a read-only value attempted" really a fatal error? #17971

Closed
@jkeenan

Description

@jkeenan

Consider this file, which is derived from ext/PerlIO-scalar/t/scalar.t in the Perl 5 core distribution:

$ cat xscalar.t 
#!./perl

BEGIN {
    unless (find PerlIO::Layer 'perlio') {
	print "1..0 # Skip: not perlio\n";
	exit 0;
    }
    require Config;
    if (($Config::Config{'extensions'} !~ m!\bPerlIO/scalar\b!) ){
        print "1..0 # Skip -- Perl configured without PerlIO::scalar module\n";
        exit 0;
    }
}

use Fcntl qw(SEEK_SET SEEK_CUR SEEK_END); # Not 0, 1, 2 everywhere.
use Errno qw(EACCES);

$| = 1;

use Test::More tests =>   5;

# [perl #40267] PerlIO::scalar doesn't respect readonly-ness
{
    ok(!(defined open(F, '>', \undef)), "[perl #40267] - $!");
    close F;

    my $ro = \43;
    ok(!(defined open(F, '>', $ro)), $!);
    is($!+0, EACCES, "check we get a read-onlyish error code");
    close F;
    # but we can read from it
    ok(open(F, '<', $ro), $!);
    is(<F>, 43);
    close F;
}

Let's run it:

$ prove -v xscalar.t 
xscalar.t .. 
1..5
ok 1 - [perl \#40267] - Permission denied
ok 2 - Permission denied
ok 3 - check we get a read-onlyish error code
ok 4 - Bad file descriptor
ok 5
ok
All tests successful.
Files=1, Tests=5,  0 wallclock secs ( 0.02 usr  0.00 sys +  0.03 cusr  0.01 csys =  0.06 CPU)
Result: PASS

Unremarkable. But now let's modify it to run it with warnings.

$ cat yscalar.t 
#!./perl -w

BEGIN {
    unless (find PerlIO::Layer 'perlio') {
	print "1..0 # Skip: not perlio\n";
	exit 0;
    }
...
# As before

Let's run it.

$ prove -v yscalar.t 
yscalar.t .. 
1..5
Modification of a read-only value attempted at yscalar.t line 24.
ok 1 - [perl \#40267] - Permission denied
ok 2 - Permission denied
ok 3 - check we get a read-onlyish error code
ok 4 - Bad file descriptor
ok 5
Modification of a read-only value attempted at yscalar.t line 28.
ok
All tests successful.
Files=1, Tests=5,  0 wallclock secs ( 0.02 usr  0.00 sys +  0.05 cusr  0.00 csys =  0.07 CPU)
Result: PASS

Two warnings are emitted.

Now I might want to suppress these with a no warnings 'XXXXX; in scope. However, when I go to perldoc perldiag to learn what category to use to replace XXXXX, I see that this warning is classified F as in fatal.

Modification of a read-only value attempted
    (F) You tried, directly or indirectly, to change the value of a
    constant. You didn't, of course, try "2 = 1", because the compiler
    catches that. 

For Category F, we have:

(F) A fatal error (trappable).

Problem: The error wasn't fatal (for an ordinary definition of "fatal"). The program kept on running. Nor did we attempt to trap the error.

So, is pod/perldiag.pod wrong with respect to categorizing "Modification of a read-only value attempted"?

Thank you very much.
Jim Keenan

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions