Date: Tue, 24 Apr 2012 21:49:29 +0200 From: =?ISO-8859-1?Q?Jean-S=E9bastien_P=E9dron?= <dumbbell@FreeBSD.org> To: freebsd-current@freebsd.org Subject: segfault in vfscanf(3): clang and __restrict usage Message-ID: <4F9703C9.8080503@FreeBSD.org>
next in thread | raw e-mail | index | archive | help
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 <stdio.h> 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 <bsd.prog.mk> --------------090407000900020908050709--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4F9703C9.8080503>