From owner-freebsd-current@FreeBSD.ORG Tue Apr 24 19:49:32 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 113A5106566B for ; Tue, 24 Apr 2012 19:49:32 +0000 (UTC) (envelope-from dumbbell@FreeBSD.org) Received: from mail.made4.biz (unknown [IPv6:2001:41d0:1:7018::1:3]) by mx1.freebsd.org (Postfix) with ESMTP id 907DA8FC0A for ; Tue, 24 Apr 2012 19:49:31 +0000 (UTC) Received: from [2a01:e35:8b50:830:290:f5ff:fe9d:b78c] (helo=magellan.dumbbell.fr) by mail.made4.biz with esmtpsa (TLSv1:DHE-RSA-CAMELLIA256-SHA:256) (Exim 4.77 (FreeBSD)) (envelope-from ) id 1SMljt-0007y2-Pp for freebsd-current@freebsd.org; Tue, 24 Apr 2012 21:49:30 +0200 Message-ID: <4F9703C9.8080503@FreeBSD.org> Date: Tue, 24 Apr 2012 21:49:29 +0200 From: =?ISO-8859-1?Q?Jean-S=E9bastien_P=E9dron?= User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:11.0) Gecko/20120419 Thunderbird/11.0.1 MIME-Version: 1.0 To: freebsd-current@freebsd.org X-Enigmail-Version: 1.4 Content-Type: multipart/mixed; boundary="------------090407000900020908050709" Subject: 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: Tue, 24 Apr 2012 19:49:32 -0000 This is a multi-part message in MIME format. --------------090407000900020908050709 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi everyone, 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"); The same libc, compiled with GCC, doesn't segfault. When it encounters a character class, __svfscanf() calls convert_ccl(): static const int suppress; #define SUPPRESS_PTR ((void *)&suppress) static __inline int convert_ccl(FILE *fp, char * __restrict p, [...]) { [...] if (p == SUPPRESS_PTR) { [...] } else { [...] } [...] } In this case, there's no argument following the format string, and convert_ccl is called with p = SUPPRESS_PTR. Therefore, we should enter the if{} block. But when compiled with clang, we enter the else{} block (causing the segfault). I made a small program that shows the problem (attached): it seems to be related to the __restrict qualifier. Compiled with GCC: ./ptr-comp p=0x600ac8 vs. SUPPRESS_PTR=0x600ac8 p == SUPPRESS_PTR Compiled with clang: ./ptr-comp p=0x4007dc vs. SUPPRESS_PTR=0x4007dc p != SUPPRESS_PTR -> WRONG - 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. What do you think? - -- Jean-Sébastien Pédron -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (FreeBSD) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk+XA8kACgkQa+xGJsFYOlOt9wCffUwQ344hfanDzU27wdgW5C+t 4fYAoKPh26OW/ge+VbLaOMTT/YtUYOwM =OblW -----END PGP SIGNATURE----- --------------090407000900020908050709 Content-Type: text/plain; charset=UTF-8; name="ptr-comp.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="ptr-comp.c" #include static const int suppress; #define SUPPRESS_PTR ((void *)&suppress) void func(char * __restrict p) { printf("p=%p vs. SUPPRESS_PTR=%p\n", p, SUPPRESS_PTR); if (p == SUPPRESS_PTR) printf("p == SUPPRESS_PTR\n"); else printf("p != SUPPRESS_PTR -> WRONG\n"); } int main(int argc, char *argv []) { char *p; p = SUPPRESS_PTR; func(p); return (0); } --------------090407000900020908050709 Content-Type: text/plain; charset=UTF-8; name="Makefile" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="Makefile" PROG = ptr-comp .include --------------090407000900020908050709--