CURL 7.19.0をLLVM-GCC 4.2でコンパイルすると、test539が失敗する。LLVM-GCC固有の問題なのか、GCC 4.2の問題なのかは知らない。
標準は、char *strcat(char *restrict s1, const char *restrict s2);
が第一引数s1の末尾に第二引数s2の内容をコピーしてからs1を返すと定めている。充分な最適化オプションを指定し、-fno-builtinを指定しなければ、GCCはstrcatをインライン展開するかもしれない。以下のコードはtests/libtest/lib539.cから抜粋した。
newURL = strcat (strcpy ((char*)malloc (strlen (URL) + 3), URL), "./");
新しく確保した領域にURL
と"./"
を連結した文字列を保存する。newURL
はmalloc
で確保した領域の先頭のアドレスを指すだろう。懐かしさこそ感じれど、このコード自体にどうというところはない。
p = malloc(strlen(URL) + 3); p = strcpy(p, URL); newURL = strcat(p, "./"); assert(p == newURL);
標準はassert
が成功することを保証する。LLVM-GCC 4.2はstrcat
をstrlen
とmemcpy
に展開する。なにかがおかしくなる。展開の結果を擬似的にCで表現すると、
p = malloc(strlen (URL) + 3); p = strcpy(p, URL); newURL = p + strlen(p); memcpy(newURL, "./", 3); assert(p == newURL);
assert
は成功しない。犯人は誰だろう。これはミステリではないので、strcatの返り値を信用しないようにコードを書き換えれば死人は甦るかもしれない。
0 件のコメント:
コメントを投稿