Skip to content

BBC: 209bfe369d triggers build-time failure in Cache-utLRU -- but only when compiled with gcc #24382

@jkeenan

Description

@jkeenan

Here we have a situation where a commit to blead has triggered a build-time failure in a CPAN library -- but apparently only when the perl was compiled with gcc. There was no breakage with the perl was compiled with clang.

CPANtesters Reports

Let's start with what I observed when testing Cache-utLRU-0.0030000 against perl-5.43.10 on Debian Linux (where the current default C-compiler is gcc-14) versus FreeBSD (where my current default C-compiler is clang19).

Different C-compilers on Same Machine

I then decided to try to build two separate perls, one with gcc, the other with clang, but on the same machine.

gcc

Compiled against commit 8b49122 using gcc-14 on Ubuntu Linux 24.04 LTS, I got a build-time failure:

Running make for G/GO/GONZUS/Cache-utLRU-0.003000.tar.gz
cp lib/Cache/utLRU.pm blib/lib/Cache/utLRU.pm
Running Mkbootstrap for utLRU ()
chmod 644 "utLRU.bs"
"/home/jkeenan/testing/blead/bin/perl" -MExtUtils::Command::MM -e 'cp_nonempty' -- utLRU.bs blib/arch/auto/Cache/utLRU/utLRU.bs 644
"/home/jkeenan/testing/blead/bin/perl" "/home/jkeenan/testing/blead/lib/perl5/5.43.10/ExtUtils/xsubpp" -noprototypes -typemap '/home/jkeenan/testing/blead/lib/perl5/5.43.10/ExtUtils/typemap' -typemap '/home/jkeenan/.cpan/build/Cache-utLRU-0.003000-0/typemap'  cache.xs > cache.xsc
mv cache.xsc cache.c
cc -c  -I. -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -std=c89 -D_XOPEN_SOURCE=700 -O2   -DVERSION=\"0.003000\" -DXS_VERSION=\"0.003000\" -fPIC "-I/home/jkeenan/testing/blead/lib/perl5/5.43.10/x86_64-linux/CORE"   cache.c
In file included from /home/jkeenan/testing/blead/lib/perl5/5.43.10/x86_64-linux/CORE/perl.h:8004,
                 from cache.xs:3:
/home/jkeenan/testing/blead/lib/perl5/5.43.10/x86_64-linux/CORE/inline.h: In function ‘Perl_cx_poploop’:
/home/jkeenan/testing/blead/lib/perl5/5.43.10/x86_64-linux/CORE/inline.h:4357:9: error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode
 4357 |         for (SV **svp = cx->blk_loop.itervar_u.svp + 1; how_many; svp++, how_many--) {
      |         ^~~
/home/jkeenan/testing/blead/lib/perl5/5.43.10/x86_64-linux/CORE/inline.h:4357:9: note: use option ‘-std=c99’, ‘-std=gnu99’, ‘-std=c11’ or ‘-std=gnu11’ to compile your code
/home/jkeenan/testing/blead/lib/perl5/5.43.10/x86_64-linux/CORE/inline.h:4374:9: error: C++ style comments are not allowed in ISO C90
 4374 |         // LV ref around a package lexical, mg_obj gives its GV
      |         ^
/home/jkeenan/testing/blead/lib/perl5/5.43.10/x86_64-linux/CORE/inline.h:4374:9: note: (this will be reported only once per input file)
In file included from cache.xs:5:
ppport.h: At top level:
ppport.h:4594: warning: "WIDEST_UTYPE" redefined
 4594 | #  define WIDEST_UTYPE U64TYPE
      | 
In file included from /home/jkeenan/testing/blead/lib/perl5/5.43.10/x86_64-linux/CORE/perl.h:3259:
/home/jkeenan/testing/blead/lib/perl5/5.43.10/x86_64-linux/CORE/handy.h:1420: note: this is the location of the previous definition
 1420 | #define WIDEST_UTYPE PERL_UINTMAX_T
      | 
make: *** [Makefile:348: cache.o] Error 1
  GONZUS/Cache-utLRU-0.003000.tar.gz
  /usr/bin/make -- NOT OK
Failed during this command:
 GONZUS/Cache-utLRU-0.003000.tar.gz           : make NO

Modulo some UTF-8 representations, this appears to be the same failure I got when testing on Debian Linux against perl-5.43.10.

clang

But when I built a perl on Ubuntu Linux at nearly the same commit as above but compiling with clang-23, I got a torrent of build-time warnings but no build-time failure.

Running make for G/GO/GONZUS/Cache-utLRU-0.003000.tar.gz
cp lib/Cache/utLRU.pm blib/lib/Cache/utLRU.pm
Running Mkbootstrap for utLRU ()
chmod 644 "utLRU.bs"
"/home/jkeenan/testing/36cbbda6b5/bin/perl" -MExtUtils::Command::MM -e 'cp_nonempty' -- utLRU.bs blib/arch/auto/Cache/utLRU/utLRU.bs 644
"/home/jkeenan/testing/36cbbda6b5/bin/perl" "/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/ExtUtils/xsubpp" -noprototypes -typemap '/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/ExtUtils/typemap' -typemap '/home/jkeenan/.cpan/build/Cache-utLRU-0.003000-1/typemap'  cache.xs > cache.xsc
mv cache.xsc cache.c
clang-23 -c  -I. -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -std=c89 -D_XOPEN_SOURCE=700 -O2   -DVERSION=\"0.003000\" -DXS_VERSION=\"0.003000\" -fPIC "-I/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE"   cache.c
In file included from cache.xs:3:
In file included from /home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE/perl.h:8004:
/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE/inline.h:4357:14: warning: GCC does not
      allow variable declarations in for loop initializers before C99 [-Wgcc-compat]
 4357 |         for (SV **svp = cx->blk_loop.itervar_u.svp + 1; how_many; svp++, how_many--) {
      |              ^
/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE/inline.h:4374:9: warning: // comments
      are not allowed in this language [-Wcomment]
 4374 |         // LV ref around a package lexical, mg_obj gives its GV
      |         ^
In file included from cache.xs:5:
./ppport.h:4594:11: warning: 'WIDEST_UTYPE' macro redefined [-Wmacro-redefined]
 4594 | #  define WIDEST_UTYPE U64TYPE
      |           ^
/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE/handy.h:1420:9: note: previous
      definition is here
 1420 | #define WIDEST_UTYPE PERL_UINTMAX_T
      |         ^
cache.xs:28:5: warning: '(' and '{' tokens introducing statement expression appear in different macro
      expansion contexts [-Wcompound-token-split-by-macro]
   28 |     EXTEND(SP, 2);
      |     ^~~~~~~~~~~~~
/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE/pp.h:459:25: note: expanded from macro
      'EXTEND'
  459 | #  define EXTEND(p,n)   STMT_START {                                    \
      |                         ^~~~~~~~~~
./ppport.h:4392:31: note: expanded from macro 'STMT_START'
 4392 | #  define STMT_START    (void)( /* gcc supports ``({ STATEMENTS; })'' */
      |                               ^

[snip many build-time warnings ]

cache.c:466:5: note: ')' token is here
  466 |     XSRETURN_EMPTY;
      |     ^~~~~~~~~~~~~~
/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE/XSUB.h:332:57: note: expanded from
      macro 'XSRETURN_EMPTY'
  332 | #define XSRETURN_EMPTY    STMT_START {                  XSRETURN(0); } STMT_END
      |                                                         ^~~~~~~~~~~
/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE/XSUB.h:322:7: note: expanded from macro
      'XSRETURN'
  322 |     } STMT_END
      |       ^~~~~~~~
./ppport.h:4393:25: note: expanded from macro 'STMT_END'
 4393 | #  define STMT_END      )
      |                         ^
cache.c:466:5: warning: '}' and ')' tokens terminating statement expression appear in different macro
      expansion contexts [-Wcompound-token-split-by-macro]
  466 |     XSRETURN_EMPTY;
      |     ^~~~~~~~~~~~~~
/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE/XSUB.h:332:70: note: expanded from
      macro 'XSRETURN_EMPTY'
  332 | #define XSRETURN_EMPTY    STMT_START {                  XSRETURN(0); } STMT_END
      |                                                                      ^
cache.c:466:5: note: ')' token is here
  466 |     XSRETURN_EMPTY;
      |     ^~~~~~~~~~~~~~
/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE/XSUB.h:332:72: note: expanded from
      macro 'XSRETURN_EMPTY'
  332 | #define XSRETURN_EMPTY    STMT_START {                  XSRETURN(0); } STMT_END
      |                                                                        ^~~~~~~~
./ppport.h:4393:25: note: expanded from macro 'STMT_END'
 4393 | #  define STMT_END      )
      |                         ^
31 warnings generated.
clang-23 -c  -I. -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -std=c89 -D_XOPEN_SOURCE=700 -O2   -DVERSION=\"0.003000\" -DXS_VERSION=\"0.003000\" -fPIC "-I/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE"   gmem.c
clang-23 -c  -I. -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -std=c89 -D_XOPEN_SOURCE=700 -O2   -DVERSION=\"0.003000\" -DXS_VERSION=\"0.003000\" -fPIC "-I/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE"   lru.c
In file included from lru.c:3:
In file included from ./lru.h:5:
In file included from /home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE/perl.h:8004:
/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE/inline.h:4357:14: warning: GCC does not
      allow variable declarations in for loop initializers before C99 [-Wgcc-compat]
 4357 |         for (SV **svp = cx->blk_loop.itervar_u.svp + 1; how_many; svp++, how_many--) {
      |              ^
/home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/CORE/inline.h:4374:9: warning: // comments
      are not allowed in this language [-Wcomment]
 4374 |         // LV ref around a package lexical, mg_obj gives its GV
      |         ^
2 warnings generated.
rm -f blib/arch/auto/Cache/utLRU/utLRU.so
clang-23  -shared -O2 -L/usr/local/lib -fstack-protector-strong  cache.o gmem.o lru.o  -o blib/arch/auto/Cache/utLRU/utLRU.so  \
      \
  
chmod 755 blib/arch/auto/Cache/utLRU/utLRU.so
  GONZUS/Cache-utLRU-0.003000.tar.gz
  /usr/bin/make -- OK
The current configuration of allow_installing_outdated_dists is 'ask/no', but for this option we would need 'CPAN::DistnameInfo' installed. Please install 'CPAN::DistnameInfo' as soon as possible. As long as we are not equipped with 'CPAN::DistnameInfo' this option does not take effect
Running make test for GONZUS/Cache-utLRU-0.003000.tar.gz
"/home/jkeenan/testing/36cbbda6b5/bin/perl" -MExtUtils::Command::MM -e 'cp_nonempty' -- utLRU.bs blib/arch/auto/Cache/utLRU/utLRU.bs 644
PERL_DL_NONLAZY=1 "/home/jkeenan/testing/36cbbda6b5/bin/perl" "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/01_use.t ......... ok   
t/02_basic.t ....... ok    
t/03_multi.t ....... ok      
t/04_visit.t ....... ok   
t/05_references.t .. ok   
t/06_keymod1.t ..... ok   
t/07_keymod2.t ..... ok   
t/08_keymod3.t ..... ok   
t/09_keymod4.t ..... ok   
All tests successful.
Files=9, Tests=2443,  1 wallclock secs ( 0.04 usr  0.01 sys +  0.32 cusr  0.04 csys =  0.41 CPU)
Result: PASS
  GONZUS/Cache-utLRU-0.003000.tar.gz
  /usr/bin/make test -- OK
Running make install for GONZUS/Cache-utLRU-0.003000.tar.gz
"/home/jkeenan/testing/36cbbda6b5/bin/perl" -MExtUtils::Command::MM -e 'cp_nonempty' -- utLRU.bs blib/arch/auto/Cache/utLRU/utLRU.bs 644
Files found in blib/arch: installing files in blib/lib into architecture dependent library tree
Installing /home/jkeenan/testing/36cbbda6b5/lib/perl5/site_perl/5.43.10/x86_64-linux/auto/Cache/utLRU/utLRU.so
Installing /home/jkeenan/testing/36cbbda6b5/lib/perl5/site_perl/5.43.10/x86_64-linux/Cache/utLRU.pm
Appending installation info to /home/jkeenan/testing/36cbbda6b5/lib/perl5/5.43.10/x86_64-linux/perllocal.pod
  GONZUS/Cache-utLRU-0.003000.tar.gz
  /usr/bin/make install  -- OK

Bisection

I noticed that the Linux build-time failures reported on CPANtesters had a clear demarcation. So I bisected with this invocation:

perl Porting/bisect.pl \
--module=Cache::utLRU \
--start=a2b66e04d9bfbd46851dcdea7cf9d9d98abe2959 \
--end=v5.43.6

Result: v5.43.5-38-g209bfe369d

209bfe369d94aa6e6d0ab65c27920b649c61cdd6 is the first bad commit
commit 209bfe369d94aa6e6d0ab65c27920b649c61cdd6
Author: Karl Williamson <khw@cpan.org>
Date:   Mon Dec 1 14:33:25 2025 -0700
Commit:     Karl Williamson <khw@cpan.org>
CommitDate: Thu Dec 4 10:07:49 2025 -0700

    handy.h: Avoid UB in nBIT_MASK()
    
    I discovered the hard way that this is undefined behavior when operating
    on the widest unsigned integer type available on the platform.
    
    I couldn't think of a way to write this without a branch that worked
    both for that condition and a zero length mask

 handy.h | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
bisect found first bad commit
That took 878 seconds.

@khwilliamson, @gonzus, can you take a look? Thank you very much.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BBCBlead Breaks CPAN - changes in blead broke a cpan module(s)sendToCPAN

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions