fix /test_bootstrap.t under -DPERL_NO_COW
authorDavid Mitchell <davem@iabyn.com>
Fri, 19 Jul 2013 20:44:32 +0000 (21:44 +0100)
committerDavid Mitchell <davem@iabyn.com>
Sun, 28 Jul 2013 09:33:39 +0000 (10:33 +0100)
These tests check whether "require test.pl" inadvertently use $& etc.
They do that by doing a simple pattern match "Perl/ =~ /Perl/, then
checking that eval '$&' returns undef.

This has always been a dodgy thing o rely on. It turns out that under
5.18.0, whether eval '$&' was undef depended on whether the intuit-only-
match codepath was taken. So:

"Perl" =~ /Perl/;   eval '$&';   # intuit-only match: returned undef
"Perl" =~ /\w+\w*/; eval '$&';   # regexec() match: returned 'Perl'.

In this branch, the same code path is now used for both intuit() and
regexec() matches, so both return 'Perl'.

So, abandon this approach to the test, and instead read in tets.pl and
grep for the test '$&' etc.
Requires  minor fixup to test.pl to avoid a false positive.

t/porting/test_bootstrap.t
t/test.pl

index df10b4c..77df867 100644 (file)
@@ -56,22 +56,23 @@ while (my $file = <$fh>) {
 # and replaced with copy-on-write.
 
 # We still allow PL_sawampersand to be enabled with
-# -Accflags=-DPERL_SAWAMPERSAND, so when that is defined we can still run
-# these tests.  When it is not enabled, PL_sawampersand makes no observable
-# difference so the tests fail.
+# -Accflags=-DPERL_SAWAMPERSAND, or with -DPERL_NO_COW, so its still worth
+# checking.
+# There's no portable, reliable way to check whether PL_sawampersand is
+# set, so instead we just "grep $`|$&|$' test.pl"
 
-require Config;
-exit unless "@{[Config::bincompat_options()]}" =~ /\bPERL_SAWAMPERSAND\b/;
-
-# This very much relies on a bug in the regexp implementation, but for now it's
-# the best way to work out whether PL_sawampersand is true.
-# Then again, PL_sawampersand *is* a bug, for precisely the reason that this
-# test can detect the behaviour change.
-
-isnt($INC{'./test.pl'}, undef, 'We loaded test.pl');
-ok("Perl rules" =~ /Perl/, 'Perl rules');
-is(eval '$&', undef, 'Nothing in test.pl mentioned $&');
-is(eval '$`', undef, 'Nothing in test.pl mentioned $`');
-is(eval '$\'', undef, 'Nothing in test.pl mentioned $\'');
-# Currently seeing any of the 3 triggers the setting of all 3.
-# $` and $' will be '' rather than undef if the regexp sets them.
+{
+    my $file = '';
+    my $fh;
+    if (ok(open(my $fh, '<', 'test.pl'), "opened test.pl")) {
+       $file = do { local $/; <$fh> };
+       $file //= '';
+    }
+    else {
+       diag("error: $!");
+    }
+    ok(length($file) > 0, "read test.pl successfully");
+    ok($file !~ /\$&/, 'Nothing in test.pl mentioned $&');
+    ok($file !~ /\$`/, 'Nothing in test.pl mentioned $`');
+    ok($file !~ /\$'/, 'Nothing in test.pl mentioned $\'');
+}
index eb4f868..89c1d4d 100644 (file)
--- a/t/test.pl
+++ b/t/test.pl
@@ -827,7 +827,7 @@ sub tempfile {
            return $try;
        }
     }
-    die "Can't find temporary file name starting 'tmp$$'";
+    die "Can't find temporary file name starting \"tmp$$\"";
 }
 
 # This is the temporary file for _fresh_perl