rurban/perl-compiler

use warnings FATAL => "prototype" cause "redefine" warning to be fatal on MSWin32/mingw

Closed this issue · 5 comments

Tested on cperl v5.26.2 + B::C 1.55_08, both win/linux, reproducible only on windows(mingw-w64/gcc-7.2):

use warnings FATAL => 'prototype';
BEGIN { sub abc {} }

warn "before redefine";
*abc = sub {};
warn "redefine OK";

END { warn "END" };

Expected output:

before redefine at /build/v8-patches/tests/perlcc/warnings-redefine.pl line 4.
redefine OK at /build/v8-patches/tests/perlcc/warnings-redefine.pl line 6.
END at /build/v8-patches/tests/perlcc/warnings-redefine.pl line 8.

Output:

before redefine at e:/build/v8-patches/tests/perlcc/warnings-redefine.pl line 4.
Subroutine main::abc redefined at e:/build/v8-patches/tests/perlcc/warnings-redefine.pl line 5.
END at e:/build/v8-patches/tests/perlcc/warnings-redefine.pl line 8.

That's strange. Why Windows only?

probably of ithreads?

That's a good idea. Thanks

@sten22 found incorrect determination of STRLEN type size.
B::C uses $Config{longsize} to determine size of STRLEN, but STRLEN is equal to size_t. Mingw-w64 on 64-bit Windows has 4-byte long int and 8-byte size_t.
So, this patch solves the issue:

--- a/Makefile.PL
+++ b/Makefile.PL
@@ -115,7 +115,7 @@ sub write_b_c_config {
     # easier hash key/value slices only came with 5.22
     for my $s (qw(archname cc ccflags
                   d_c99_variadic_macros d_dlopen d_isinf d_isnan d_longdbl dlext
-                  i_dlfcn ivdformat ivsize longsize mad nvgformat ptrsize static_ext
+                  i_dlfcn ivdformat ivsize longsize mad nvgformat ptrsize sizesize static_ext
                   usecperl usedl useithreads uselongdouble usemultiplicity usemymalloc uvuformat))
     {
         if ($CORE) {
--- a/lib/B/C.pm
+++ b/lib/B/C.pm
@@ -3414,8 +3414,8 @@ sub lexwarnsym {
       $init->add( sprintf( "%s = newSVpvn(%s, %u);", $sym, $cstring, $cur));
     } else {
       # if 8 use UVSIZE, if 4 use LONGSIZE
-      my $t = ($Config{longsize} == 8) ? "J" : "L";
-      my ($iv) = unpack($t, $pv); # unsigned longsize
+      my $t = ($Config{sizesize} == 8) ? "J" : "L";
+      my ($iv) = unpack($t, $pv); # size_t
       if ($iv >= 0 and $iv <= 2) { # specialWARN: single STRLEN
         $decl->add( sprintf( "Static const STRLEN* %s = %d;", $sym, $iv ));
         $isint = 1;

Great, thanks!