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>
index | next in thread | raw e-mail
[-- Attachment #1 --]
-----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-----
[-- Attachment #2 --]
#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);
}
[-- Attachment #3 --]
PROG = ptr-comp
.include <bsd.prog.mk>
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4F9703C9.8080503>
