Date: Wed, 25 Apr 2012 20:57:49 +0200 From: Dimitry Andric <dim@FreeBSD.org> To: =?ISO-8859-1?Q?Jean-S=E9bastien_P=E9dron?= <dumbbell@FreeBSD.org> Cc: freebsd-current@freebsd.org Subject: Re: segfault in vfscanf(3): clang and __restrict usage Message-ID: <4F98492D.8070006@FreeBSD.org> In-Reply-To: <4F9703C9.8080503@FreeBSD.org> References: <4F9703C9.8080503@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2012-04-24 21:49, Jean-S=E9bastien P=E9dron wrote: > Hi everyone, >=20 > vfscanf(3) in HEAD (r234606) segfaults when compiled with clang. For > instance, here is a call made in cmake which crashes: > fscanf(f, "%*[^\n]\n"); Using r234549 here, everything compiled with clang, but I cannot make that statement crash, whatever I do. Do you have a specific input file which crashes it? > The same libc, compiled with GCC, doesn't segfault. >=20 > When it encounters a character class, __svfscanf() calls convert_ccl():= >=20 > static const int suppress; > #define SUPPRESS_PTR ((void *)&suppress) >=20 > static __inline int > convert_ccl(FILE *fp, char * __restrict p, [...]) > { > [...] >=20 > if (p =3D=3D SUPPRESS_PTR) { > [...] > } else { > [...] > } >=20 > [...] > } =2E.. > From what I understand about __restrict, it indicates that the pointer > is the only one pointing to a resource. In vfscanf.c, "suppress" may > be pointed by several pointers at a time, so I think __restrict here > is incorrect. But I'm really not sure I got it right. And I don't know > either if clang behavior is expected. Indeed, my first impression was the same, that the use of 'restrict' is wrong here. Namely, if you tell the compiler that 'p' is the *only* pointer pointing to a specific object, and you compare it with any other pointer, the comparison will be unequal by definition. However, after asking around a bit, it seems that clang is still wrong in this particular case. Although this is probably language lawyer area, so beware. :) I have filed an LLVM PR for it here: =20 http://llvm.org/bugs/show_bug.cgi?id=3D12656=20 Meanwhile, I really wonder why the __restrict keyword was used in this implementation. There are lots of cases in vfscanf.c, where a pointer is declared __restrict, and then aliasing seems to be done anyway.=20 Besides, I'm not really sure about the potential optimization gains of adding the keyword. With our base gcc, removing all the __restrict keywords results in no binary change. With gcc 4.7, there are some very minor changes, but they are extremely unlikely to gain any performance. And with clang, there are quite some differences, but apparently it optimizes too aggressively, so more testing is required to see if the potential for bugs outweighs the performance gains.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4F98492D.8070006>