[ruby-dev:49745] [Ruby trunk Bug#12479] mistaken macro GCC_VERSION_SINCE
From:
usa@...
Date:
2016-08-04 05:59:45 UTC
List:
ruby-dev #49745
Issue #12479 has been updated by Usaku NAKAMURA.
Backport changed from 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.1: DONTNEED, 2.2: DONTNEED, 2.3: DONTNEED
----------------------------------------
Bug #12479: mistaken macro GCC_VERSION_SINCE
https://bugs.ruby-lang.org/issues/12479#change-59915
* Author: Naohisa Goto
* Status: Closed
* Priority: Normal
* Assignee:
* ruby -v:
* Backport: 2.1: DONTNEED, 2.2: DONTNEED, 2.3: DONTNEED
----------------------------------------
いつからかは不明ですが、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/