ericboesch / bitset

Bitset implementation for Ruby
MIT License
9 stars 7 forks source link

Extension fails to build with Clang 16 #7

Open asomers opened 1 year ago

asomers commented 1 year ago

Attempting to build the extension with Clang 16 fails like this:

    current directory: /home/somers/.gem/ruby/3.1/gems/bitset-1.2.0/ext/bitset
/usr/local/bin/ruby31 extconf.rb
creating Makefile

current directory: /home/somers/.gem/ruby/3.1/gems/bitset-1.2.0/ext/bitset
make DESTDIR\= sitearchdir\=./.gem.20230916-8087-i84bj2 sitelibdir\=./.gem.20230916-8087-i84bj2 clean

current directory: /home/somers/.gem/ruby/3.1/gems/bitset-1.2.0/ext/bitset
make DESTDIR\= sitearchdir\=./.gem.20230916-8087-i84bj2 sitelibdir\=./.gem.20230916-8087-i84bj2
compiling bitset.c
bitset.c:83:33: warning: function 'raise_index_error' could be declared with attribute 'noreturn' [-Wmissing-noreturn]
static void raise_index_error() {
                                ^
bitset.c:318:18: warning: implicit conversion loses integer precision: 'long' to 'int' [-Wshorten-64-to-32]
    int length = RSTRING_LEN(s);
        ~~~~~~   ^~~~~~~~~~~~~~
/usr/local/include/ruby-3.1/ruby/internal/core/rstring.h:52:27: note: expanded from macro 'RSTRING_LEN'
#define RSTRING_LEN       RSTRING_LEN
                          ^
bitset.c:509:16: warning: implicit conversion loses integer precision: 'long' to 'int' [-Wshorten-64-to-32]
    int alen = RARRAY_LEN(index_array);
        ~~~~   ^~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/ruby-3.1/ruby/internal/core/rarray.h:68:36: note: expanded from macro 'RARRAY_LEN'
#define RARRAY_LEN                 rb_array_len                 /**< @alias{rb_array_len} */
                                   ^
bitset.c:605:5: error: incompatible function pointer types passing 'VALUE (VALUE, VALUE)' (aka 'unsigned long (unsigned long, unsigned long)') to parameter of type 'VALUE (*)(VALUE)' (aka 'unsigned long (*)(unsigned long)') [-Wincompatible-function-pointer-types]
    rb_define_method(cBitset, "size", rb_bitset_size, 0);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/ruby-3.1/ruby/internal/anyargs.h:287:135: note: expanded from macro 'rb_define_method'
#define rb_define_method(klass, mid, func, arity)           RBIMPL_ANYARGS_DISPATCH_rb_define_method((arity), (func))((klass), (mid), (func), (arity))
                                                                                                                                      ^~~~~~
/usr/local/include/ruby-3.1/ruby/internal/anyargs.h:276:1: note: passing argument to parameter here
RBIMPL_ANYARGS_DECL(rb_define_method, VALUE, const char *)
^
/usr/local/include/ruby-3.1/ruby/internal/anyargs.h:254:72: note: expanded from macro 'RBIMPL_ANYARGS_DECL'
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _00(__VA_ARGS__, VALUE(*)(VALUE), int); \
                                                                       ^
bitset.c:649:5: error: incompatible function pointer types passing 'VALUE (VALUE, VALUE)' (aka 'unsigned long (unsigned long, unsigned long)') to parameter of type 'VALUE (*)(VALUE)' (aka 'unsigned long (*)(unsigned long)') [-Wincompatible-function-pointer-types]
    rb_define_method(cBitset, "reverse", rb_bitset_reverse, 0);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/ruby-3.1/ruby/internal/anyargs.h:287:135: note: expanded from macro 'rb_define_method'
#define rb_define_method(klass, mid, func, arity)           RBIMPL_ANYARGS_DISPATCH_rb_define_method((arity), (func))((klass), (mid), (func), (arity))
                                                                                                                                      ^~~~~~
/usr/local/include/ruby-3.1/ruby/internal/anyargs.h:276:1: note: passing argument to parameter here
RBIMPL_ANYARGS_DECL(rb_define_method, VALUE, const char *)
^
/usr/local/include/ruby-3.1/ruby/internal/anyargs.h:254:72: note: expanded from macro 'RBIMPL_ANYARGS_DECL'
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _00(__VA_ARGS__, VALUE(*)(VALUE), int); \
                                                                       ^
3 warnings and 2 errors generated.
*** Error code 1

My environment is:

> freebsd-version
15.0-CURRENT
> clang --version
FreeBSD clang version 16.0.6 (https://github.com/llvm/llvm-project.git llvmorg-16.0.6-0-g7cbf1a259152)
Target: x86_64-unknown-freebsd15.0
Thread model: posix
InstalledDir: /usr/bin
> ruby --version
ruby 3.1.4p223 (2023-03-30 revision 957bb7cb81) [amd64-freebsd15]
bkoski commented 2 months ago

It seems this is related to unused parameters in the size and reverse functions that aren't accounted for in the rb_define_method parameter count, and a clang change made this an error and not a warning. Opened PR #8, which appears to resolve this.

The --with-cflags=-Wno-error=incompatible-function-pointer-types workaround mentioned here also resolves the issue for me: https://github.com/grpc/grpc/issues/35148#issuecomment-2016742245

But of course preferable to fix the underlying error vs. disabling the check.