From: ngotogenome@... Date: 2016-06-10T16:44:50+00:00 Subject: [ruby-dev:49660] [Ruby trunk Bug#12479] mistaken macro GCC_VERSION_SINCE Issue #12479 has been reported by Naohisa Goto. ---------------------------------------- Bug #12479: mistaken macro GCC_VERSION_SINCE https://bugs.ruby-lang.org/issues/12479 * Author: Naohisa Goto * Status: Open * Priority: Normal * Assignee: * ruby -v: * Backport: 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN ---------------------------------------- いつからかは不明ですが、Solaris 10上の古いGCCでコンパイルすると、以下のエラーにて make test-all が失敗します。(r55344にて確認。) ~~~ 1) Failure: TestMkmf::TestConvertible#test_typeof_builtin [/XXXXX-55344/test/mkmf/test_convertible.rb:9]: convertible_int: checking for convertible type of short... -------------------- short -------------------- convertible_int: checking for convertible type of int... -------------------- int -------------------- convertible_int: checking for convertible type of long... -------------------- long -------------------- convertible_int: checking for convertible type of signed short... -------------------- failed "/usr/sfw/bin/gcc -o conftest -I. -I/XXXXX-55344/.ext/include/sparc-solaris2.10 -I/XXXXX-55344/include -I./test -I/usr/local/include -D_XOPEN_SOURCE=500 -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -O conftest.c -L. -L/XXXXX-55344 -Wl,-R/XXXXX-55344 -L. -L/usr/local/lib -R/usr/local/lib -Wl,-R/XXXXX/sparc32-gcc3-trunk/lib -L/XXXXX/sparc32-gcc3-trunk/lib -lruby-static -lpthread -lrt -lgmp -lsocket -ldl -lcrypt -lm -lc" In file included from /XXXXX-55344/include/ruby.h:33, from conftest.c:1: /XXXXX-55344/include/ruby/ruby.h:567: warning: `error' attribute directive ignored /XXXXX-55344/include/ruby/ruby.h:592: warning: `error' attribute directive ignored /XXXXX-55344/include/ruby/ruby.h:593: warning: `warning' attribute directive ignored /XXXXX-55344/include/ruby/ruby.h:1346: warning: `warning' attribute directive ignored checked program was: /* begin */ 1: #include "ruby.h" 2: 3: int main(int argc, char **argv) 4: { 5: return 0; 6: } /* end */ ~~~ コンパイルに使用したGCCのバージョンは、以下のように、たいへん古いものです。 ~~~ $ /usr/sfw/bin/gcc --version gcc (GCC) 3.4.3 (csl-sol210-3_4-branch+sol_rpath) Copyright (C) 2004 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ~~~ 上記にて Warningが出ていた include/ruby/ruby.h の567行め付近は以下の内容です。 ~~~ 566: #if GCC_VERSION_SINCE(4,4,0) 567: void rb_check_safe_str(VALUE) __attribute__((error("rb_check_safe_str() and Check_SafeStr() are obsolete; use SafeStringValue() instead"))); 568: # define Check_SafeStr(v) rb_check_safe_str((VALUE)(v)) 569: #else ~~~ `#if GCC_VERSION_SINCE(4,4,0)` の中なので、GCC 3.4.3 ではコンパイルされないはずの部分なのに、なぜかコンパイルされてしまい、知らないattributeなので無視した旨のwarningが出てしまっています。 このマクロ GCC_VERSION_SINCE は、include/ruby/defines.h にて、以下のように定義されていました。 ~~~ #define GCC_VERSION_SINCE(major, minor, patchlevel) \ (defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) && \ ((__GNUC__ > (major)) || \ ((__GNUC__ == (major) && \ (__GNUC_MINOR__ > (minor)) || \ (__GNUC_MINOR__ == (minor) && __GNUC_PATCHLEVEL__ >= (patchlevel)))))) ~~~ 上記マクロの下3行を端的に表現すると `(X && Y || Z)` となり、 X は `__GNUC__ == (major)` Y は `(__GNUC_MINOR__ > (minor))` Z は `(__GNUC_MINOR__ == (minor) && __GNUC_PATCHLEVEL__ >= (patchlevel))` ということになりますが、 `X && Y || Z` は括弧が無いため左結合となり `(X && Y) || Z` と解釈され、 つまり、Z が正の場合は、X や Y の値と無関係に、この条件式は正になります。 そして、`#if GCC_VERSION_SINCE(4,4,0)` に対する GCC 3.4.3 は、Z が正となる条件にぴったり当てはまることになります。 今更 GCC 3系列のような古いGCCでコンパイルを試みる人はほとんど居なかったので、気がつかれなかったのだと思います。 なお、`X && (Y || Z)` が本来希望していた演算内容となりますので、そうなるように括弧を追加します。 -- https://bugs.ruby-lang.org/