ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:121769] [Ruby Bug#21293] C23/GCC 15 build breakage with rb_define_method() and friends
@ 2025-04-29 12:59 alanwu (Alan Wu) via ruby-core
  2025-05-01  5:15 ` [ruby-core:121787] " shyouhei (Shyouhei Urabe) via ruby-core
  0 siblings, 1 reply; 2+ messages in thread
From: alanwu (Alan Wu) via ruby-core @ 2025-04-29 12:59 UTC (permalink / raw)
  To: ruby-core; +Cc: alanwu (Alan Wu)

Issue #21293 has been reported by alanwu (Alan Wu).

----------------------------------------
Bug #21293: C23/GCC 15 build breakage with rb_define_method() and friends
https://bugs.ruby-lang.org/issues/21293

* Author: alanwu (Alan Wu)
* Status: Open
* Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
GCC 15 defaults to `-std=gnu23`, which breaks rb_define_method() in some corner cases:

```diff
diff --git a/object.c b/object.c
index 5a379e9..958f421 100644
--- a/object.c
+++ b/object.c
@@ -4613,7 +4613,8 @@ InitVM_Object(void)
     rb_cFalseClass = rb_define_class("FalseClass", rb_cObject);
     rb_cFalseClass_to_s = rb_fstring_enc_lit("false", rb_usascii_encoding());
     rb_vm_register_global_object(rb_cFalseClass_to_s);
-    rb_define_method(rb_cFalseClass, "to_s", rb_false_to_s, 0);
+    int zero = 0;
+    rb_define_method(rb_cFalseClass, "to_s", rb_false_to_s, zero);
     rb_define_alias(rb_cFalseClass, "inspect", "to_s");
     rb_define_method(rb_cFalseClass, "&", false_and, 1);
     rb_define_method(rb_cFalseClass, "|", false_or, 1);
```

Applying the above is fine prior to C23, but on GCC 15 it triggers a build error:

```text
compiling object.c
In file included from ./include/ruby/ruby.h:27,
                 from constant.h:13,
                 from object.c:22:
object.c: In function 'InitVM_Object':
./include/ruby/internal/anyargs.h:288:135: error: passing argument 3 of 'rb_define_method_m3' from incompatible pointer type [-Wincompatible-pointer-types]
  288 | #define rb_define_method(klass, mid, func, arity)           RBIMPL_ANYARGS_DISPATCH_rb_define_method((arity), (func))((klass), (mid), (func), (arity))
      |                                                                                                                                       ^~~~~~
      |                                                                                                                                       |
      |                                                                                                                                       VALUE (*)(VALUE) {aka long unsigned int (*)(long unsigned int)}
object.c:4617:5: note: in expansion of macro 'rb_define_method'
 4617 |     rb_define_method(rb_cFalseClass, "to_s", rb_false_to_s, kek);
      |     ^~~~~~~~~~~~~~~~
./include/ruby/internal/anyargs.h:277:21: note: expected 'VALUE (*)(void)' {aka 'long unsigned int (*)(void)'} but argument is of type 'VALUE (*)(VALUE)' {aka 'long unsigned int (*)(long unsigned int)'}
  277 | RBIMPL_ANYARGS_DECL(rb_define_method, VALUE, const char *)
      |                     ^~~~~~~~~~~~~~~~
./include/ruby/internal/anyargs.h:252:41: note: in definition of macro 'RBIMPL_ANYARGS_DECL'
  252 | RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m3(__VA_ARGS__, VALUE(*)(ANYARGS), int); \
      |                                         ^~~
object.c:1605:1: note: 'rb_false_to_s' declared here
 1605 | rb_false_to_s(VALUE obj)
      | ^~~~~~~~~~~~~
At top level:
cc1: note: unrecognized command-line option '-Wno-self-assign' may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option '-Wno-parentheses-equality' may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option '-Wno-constant-logical-operand' may have been intended to silence earlier diagnostics
make: *** [Makefile:464: object.o] Error 1
```

This also happens for C method that takes a large number of arguments.


This because in C23 `void foo();` no longers means "foo takes an unspecified number of arguments" anymore, and there is no way to implement a working `ANYARGS` AFAIK.

Not something people would run into in practice, I hope.

(related: #21286 but this one is not Windows specific)



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [ruby-core:121787] [Ruby Bug#21293] C23/GCC 15 build breakage with rb_define_method() and friends
  2025-04-29 12:59 [ruby-core:121769] [Ruby Bug#21293] C23/GCC 15 build breakage with rb_define_method() and friends alanwu (Alan Wu) via ruby-core
@ 2025-05-01  5:15 ` shyouhei (Shyouhei Urabe) via ruby-core
  0 siblings, 0 replies; 2+ messages in thread
From: shyouhei (Shyouhei Urabe) via ruby-core @ 2025-05-01  5:15 UTC (permalink / raw)
  To: ruby-core; +Cc: shyouhei (Shyouhei Urabe)

Issue #21293 has been updated by shyouhei (Shyouhei Urabe).


Yes...  This is a macro expansion glitch.

Basically if `zero` was an integer constant expression (which it isn't, by the way, in your diff), `__buiitin_constant_p` in [this] line would be true, and `rb_define_method` macro would be expanded as expected.  This normally works because a C function tends to have compile-time fixed arity.  People do not need to pass dynamic value here.  But if they do...  It breaks, like you reported.

`rb_define_method` is a rusty API.  Its design dates back to when matz still used K&R C.  C evolved since then.  We have coped with the language updates but are having hard times recently.  Maybe either we want a "modern" C API, or we want to stop following the C standard (which many projects do anyway).



[this]: https://github.com/ruby/ruby/blob/994dadfbf4d090e73f996bafcc9d3d64892a57c6/include/ruby/internal/anyargs.h#L114

----------------------------------------
Bug #21293: C23/GCC 15 build breakage with rb_define_method() and friends
https://bugs.ruby-lang.org/issues/21293#change-112845

* Author: alanwu (Alan Wu)
* Status: Open
* Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
GCC 15 defaults to `-std=gnu23`, which breaks rb_define_method() in some corner cases:

```diff
diff --git a/object.c b/object.c
index 5a379e9..958f421 100644
--- a/object.c
+++ b/object.c
@@ -4613,7 +4613,8 @@ InitVM_Object(void)
     rb_cFalseClass = rb_define_class("FalseClass", rb_cObject);
     rb_cFalseClass_to_s = rb_fstring_enc_lit("false", rb_usascii_encoding());
     rb_vm_register_global_object(rb_cFalseClass_to_s);
-    rb_define_method(rb_cFalseClass, "to_s", rb_false_to_s, 0);
+    int zero = 0;
+    rb_define_method(rb_cFalseClass, "to_s", rb_false_to_s, zero);
     rb_define_alias(rb_cFalseClass, "inspect", "to_s");
     rb_define_method(rb_cFalseClass, "&", false_and, 1);
     rb_define_method(rb_cFalseClass, "|", false_or, 1);
```

Applying the above is fine prior to C23, but on GCC 15 it triggers a build error:

```text
compiling object.c
In file included from ./include/ruby/ruby.h:27,
                 from constant.h:13,
                 from object.c:22:
object.c: In function 'InitVM_Object':
./include/ruby/internal/anyargs.h:288:135: error: passing argument 3 of 'rb_define_method_m3' from incompatible pointer type [-Wincompatible-pointer-types]
  288 | #define rb_define_method(klass, mid, func, arity)           RBIMPL_ANYARGS_DISPATCH_rb_define_method((arity), (func))((klass), (mid), (func), (arity))
      |                                                                                                                                       ^~~~~~
      |                                                                                                                                       |
      |                                                                                                                                       VALUE (*)(VALUE) {aka long unsigned int (*)(long unsigned int)}
object.c:4617:5: note: in expansion of macro 'rb_define_method'
 4617 |     rb_define_method(rb_cFalseClass, "to_s", rb_false_to_s, kek);
      |     ^~~~~~~~~~~~~~~~
./include/ruby/internal/anyargs.h:277:21: note: expected 'VALUE (*)(void)' {aka 'long unsigned int (*)(void)'} but argument is of type 'VALUE (*)(VALUE)' {aka 'long unsigned int (*)(long unsigned int)'}
  277 | RBIMPL_ANYARGS_DECL(rb_define_method, VALUE, const char *)
      |                     ^~~~~~~~~~~~~~~~
./include/ruby/internal/anyargs.h:252:41: note: in definition of macro 'RBIMPL_ANYARGS_DECL'
  252 | RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m3(__VA_ARGS__, VALUE(*)(ANYARGS), int); \
      |                                         ^~~
object.c:1605:1: note: 'rb_false_to_s' declared here
 1605 | rb_false_to_s(VALUE obj)
      | ^~~~~~~~~~~~~
At top level:
cc1: note: unrecognized command-line option '-Wno-self-assign' may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option '-Wno-parentheses-equality' may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option '-Wno-constant-logical-operand' may have been intended to silence earlier diagnostics
make: *** [Makefile:464: object.o] Error 1
```

This also happens for C method that takes a large number of arguments.

This because in C23 `void foo();` no longers means "foo takes an unspecified number of arguments", and there is no way to implement a working `ANYARGS` AFAIK.

Not something people would run into in practice, I hope.

(related: #21286 but this one is not Windows specific)



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-05-01  5:15 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-29 12:59 [ruby-core:121769] [Ruby Bug#21293] C23/GCC 15 build breakage with rb_define_method() and friends alanwu (Alan Wu) via ruby-core
2025-05-01  5:15 ` [ruby-core:121787] " shyouhei (Shyouhei Urabe) via ruby-core

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).