clang-3.1でruby-trunkが-Werror=shorten-64-to-32に引っかかる件
まとめているうちに修正されちゃった(r35874)んだけど、まあ途中まで書いたし残しとこう。
誰の発言だったか忘れちゃったんですが、TLで「ruby-1.9.3がclang-3.1でコンパイルとおらない」というのを見かけたので試してみた。
compiling regparse.c regparse.c:582:15: error: implicit conversion loses integer precision: 'st_index_t' (aka 'unsigned long') to 'int' [-Werror,-Wshorten-64-to-32] return t->num_entries; ~~~~~~ ~~~^~~~~~~~~~~ 1 error generated.
メッセージにあるとおり、regparse.cのonig_number_of_names()の返り値がintなのにt->num_entriesがunsigned longなので-Werror=shorten-64-to-32に該当するってこと。人間がコード読んでもそのとおりなのを確認(NameTableはst_table include/ruby/st.h)。
extern int onig_number_of_names(regex_t* reg) { NameTable* t = (NameTable* )reg->name_table; if (IS_NOT_NULL(t)) return t->num_entries; else return 0; }
また、trunkでも同様のコンパイルエラーが再現した。(前述のとおり6/2に修正済み)
調べてみた感じ、
- shorten-64-to-32は、Appleのgccに入ってた独自オプションである
- clangにも同様のオプションがある
- clang-3.1で判定が以前より賢くなったので以前にはとおっていたところが見つかるようになった
といったところ。Xcode 4.3.2のclangは3.1リリースちょっと前の開発版で、そのへんの差がでたってことかな。clangの実装についてはテスト見るのが手っ取り早いので、opensource.apple.comのclangと比べてみよう。
--- .../clang-318.0.45/src/tools/clang/test/Sema/conversion-64-32.c 2011-11-09 14:02:00.000000000 +0900 +++ Sema/conversion-64-32.c 2012-06-05 00:03:39.000000000 +0900 @@ -13,3 +13,7 @@ int4 v127 = a; // no warning. return v127; } + +int test2(long v) { + return v / 2; // expected-warning {{implicit conversion loses integer precision: 'long' to 'int'}} +}
test/Sema/conversion-64-32.cになんか追加があるけれど、これが該当するものかはわからないねえ。