From owner-freebsd-current@FreeBSD.ORG Wed Apr 25 18:57:50 2012 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 28AD91065670; Wed, 25 Apr 2012 18:57:50 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from tensor.andric.com (cl-327.ede-01.nl.sixxs.net [IPv6:2001:7b8:2ff:146::2]) by mx1.freebsd.org (Postfix) with ESMTP id D99438FC1D; Wed, 25 Apr 2012 18:57:49 +0000 (UTC) Received: from [IPv6:2001:7b8:3a7:0:91a4:9332:24dd:72e6] (unknown [IPv6:2001:7b8:3a7:0:91a4:9332:24dd:72e6]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by tensor.andric.com (Postfix) with ESMTPSA id 0AFAB5C59; Wed, 25 Apr 2012 20:57:49 +0200 (CEST) Message-ID: <4F98492D.8070006@FreeBSD.org> Date: Wed, 25 Apr 2012 20:57:49 +0200 From: Dimitry Andric Organization: The FreeBSD Project User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20120410 Thunderbird/12.0 MIME-Version: 1.0 To: =?ISO-8859-1?Q?Jean-S=E9bastien_P=E9dron?= References: <4F9703C9.8080503@FreeBSD.org> In-Reply-To: <4F9703C9.8080503@FreeBSD.org> X-Enigmail-Version: 1.4.1 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Cc: freebsd-current@freebsd.org Subject: Re: segfault in vfscanf(3): clang and __restrict usage X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Apr 2012 18:57:50 -0000 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.