[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]