Bug #12479
closedmistaken macro GCC_VERSION_SINCE
Description
いつからかは不明ですが、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)
が本来希望していた演算内容となりますので、そうなるように括弧を追加します。
Updated by ngoto (Naohisa Goto) almost 8 years ago
- Status changed from Open to Closed
Applied in changeset r55371.
- include/ruby/defines.h (GCC_VERSION_SINCE): Fix logic error by
adding parentheses. Fix failures of TestMkmf::TestConvertible
with GCC 3.4.3 on Solaris 10. [Bug #12479] [ruby-dev:49660]
Updated by usa (Usaku NAKAMURA) over 7 years ago
- Backport changed from 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.1: DONTNEED, 2.2: DONTNEED, 2.3: DONTNEED