ruby-changes:69893
From: Dimitry <ko1@a...>
Date: Wed, 24 Nov 2021 17:49:52 +0900 (JST)
Subject: [ruby-changes:69893] 06aafeb4b3 (ruby_2_7): Fix clang -Wcompound-token-split-by-macro warning in ruby.h
https://git.ruby-lang.org/ruby.git/commit/?id=06aafeb4b3 From 06aafeb4b3a855966262da4855a5ba43d672d5e4 Mon Sep 17 00:00:00 2001 From: Dimitry Andric <dimitry@a...> Date: Sat, 15 May 2021 20:58:26 +0200 Subject: Fix clang -Wcompound-token-split-by-macro warning in ruby.h Building certain ruby gem native extensions (such as thrift), with clang 12.0.0 or later fails, because they have -Werror in their CFLAGS, resulting in complaints about the expansion of the `rb_intern()` macro: ``` current directory: /wrkdirs/usr/ports/devel/rubygem-thrift/work/stage/usr/local/lib/ruby/gems/2.7/gems/thrift-0.14.0/ext make "DESTDIR=" compiling binary_protocol_accelerated.c binary_protocol_accelerated.c:404:68: error: '(' and '{' tokens introducing statement expression appear in different macro expansion contexts [-Werror,-Wcompound-token-split-by-macro] VALUE thrift_binary_protocol_class = rb_const_get(thrift_module, rb_intern("BinaryProtocol")); ^~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/local/include/ruby-2.7/ruby/ruby.h:1847:23: note: expanded from macro 'rb_intern' __extension__ (RUBY_CONST_ID_CACHE((ID), (str))) : \ ^ binary_protocol_accelerated.c:404:68: note: '{' token is here VALUE thrift_binary_protocol_class = rb_const_get(thrift_module, rb_intern("BinaryProtocol")); ^~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/local/include/ruby-2.7/ruby/ruby.h:1847:24: note: expanded from macro 'rb_intern' __extension__ (RUBY_CONST_ID_CACHE((ID), (str))) : \ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/local/include/ruby-2.7/ruby/ruby.h:1832:5: note: expanded from macro 'RUBY_CONST_ID_CACHE' { \ ^ ``` Part of the `rb_intern()` macro expands to `(RUBY_CONST_ID_CACHE((ID), (str)))`, and in turn `RUBY_CONST_ID_CACHE()` expands to a brace enclosed compound statement. The intended effect is to get a gcc statement expression, which is normally delimited by `({ ... })`. However, clang 12.0.0 and later have a warning enabled by default, about pasting together the `(` and `{` tokens via different macros (see <https://github.com/llvm/llvm-project/commit/0e00a95b4fad5e72851de012d3a0b2c2d01f8685>). To work around this warning: * Add `RUBY_CONST_ID_CACHE_NB()` (i.e. no-brace) which contains the code itself, without any braces * `RUBY_CONST_ID_CACHE()` which uses `RUBY_CONST_ID_CACHE_NB()`, but puts braces around it (so no existing code using this macro breaks) * Finally, change `rb_intern()` so the `__extension__` directly creates a gcc statement expression, using the `RUBY_CONST_ID_CACHE_NB()` macro --- include/ruby/ruby.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index 1ce73d55599..bd95d5b0b10 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -1828,12 +1828,14 @@ VALUE rb_sym2str(VALUE); https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1828 VALUE rb_to_symbol(VALUE name); VALUE rb_check_symbol(volatile VALUE *namep); -#define RUBY_CONST_ID_CACHE(result, str) \ - { \ +#define RUBY_CONST_ID_CACHE_NB(result, str) \ static ID rb_intern_id_cache; \ if (!rb_intern_id_cache) \ rb_intern_id_cache = rb_intern2((str), (long)strlen(str)); \ - result rb_intern_id_cache; \ + result rb_intern_id_cache; +#define RUBY_CONST_ID_CACHE(result, str) \ + { \ + RUBY_CONST_ID_CACHE_NB(result, str) \ } #define RUBY_CONST_ID(var, str) \ do RUBY_CONST_ID_CACHE((var) =, (str)) while (0) @@ -1844,7 +1846,7 @@ VALUE rb_check_symbol(volatile VALUE *namep); https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1846 * since gcc-2.7.2.3 at least. */ #define rb_intern(str) \ (__builtin_constant_p(str) ? \ - __extension__ (RUBY_CONST_ID_CACHE((ID), (str))) : \ + __extension__ ({RUBY_CONST_ID_CACHE_NB((ID), (str))}) : \ rb_intern(str)) #define rb_intern_const(str) \ (__builtin_constant_p(str) ? \ -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/