segfault in vfscanf(3): clang and __restrict usage

Jean-Sébastien Pédron dumbbell at FreeBSD.org
Thu Apr 26 09:41:17 UTC 2012


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 25.04.2012 21:40, Dimitry Andric wrote:
> I think the easiest solution for now is to #undef __restrict at the
> top of both lib/libc/stdio/vfscanf.c and lib/libc/stdio/vfwscanf.c,
> then recompile and reinstall libc.

I attached a patch that removes the __restrict keyword in the
convert_* functions because I believe it's incorrect.

In vfscanf.c, I kept the last one in parseint() because I believe it's
correct: the restricted pointer is used to initialized another one and
comparisons are made only between those two pointers. But I didn't
check if clang optimized out the comparisons. What do you think about
the correctness here?

We can't remove it in vfwscanf(), vfwscanf_l() and __vfwscanf()
(vfwscanf.c) because it's required by the vfwscanf(3) API.

The patch also removes some trailing whitespaces while here.

I'm rebuilding world with this patch and will check that cmake is
working again (the program which shows segfaults for me).

Boris, could you please test it and tell me if cupsd works again for
you too? You just need to rebuild/reinstall the libc, not cups.

Dimitry, thank you for the reporting the problem to LLVM!

- -- 
Jean-Sébastien Pédron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (FreeBSD)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk+ZGDoACgkQa+xGJsFYOlOA4ACdH7vH4XfjH6nxcV/axmAYKUKq
8hoAoMrfly9RkUL0UKSKsmbxIiBz2YZy
=GFTc
-----END PGP SIGNATURE-----
-------------- next part --------------
diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c
index 6a6b19c..5316a7c 100644
--- a/lib/libc/stdio/vfscanf.c
+++ b/lib/libc/stdio/vfscanf.c
@@ -125,7 +125,7 @@ static const mbstate_t initial_mbs;
  */
 
 static __inline int
-convert_char(FILE *fp, char * __restrict p, int width)
+convert_char(FILE *fp, char * p, int width)
 {
 	int n, nread;
 
@@ -152,7 +152,7 @@ convert_char(FILE *fp, char * __restrict p, int width)
 		nread += sum;
 	} else {
 		size_t r = __fread(p, 1, width, fp);
-		
+
 		if (r == 0)
 			return (-1);
 		nread += r;
@@ -205,7 +205,7 @@ convert_wchar(FILE *fp, wchar_t *wcp, int width)
 }
 
 static __inline int
-convert_ccl(FILE *fp, char * __restrict p, int width, const char *ccltab)
+convert_ccl(FILE *fp, char * p, int width, const char *ccltab)
 {
 	char *p0;
 	int n;
@@ -304,7 +304,7 @@ convert_wccl(FILE *fp, wchar_t *wcp, int width, const char *ccltab)
 }
 
 static __inline int
-convert_string(FILE *fp, char * __restrict p, int width)
+convert_string(FILE *fp, char * p, int width)
 {
 	char *p0;
 	int n;
@@ -467,7 +467,7 @@ parseint(FILE *fp, char * __restrict buf, int width, int base, int flags)
 				goto ok;
 			}
 			break;
-					
+
 		/*
 		 * x ok iff flag still set & 2nd char (or 3rd char if
 		 * we have a sign).
diff --git a/lib/libc/stdio/vfwscanf.c b/lib/libc/stdio/vfwscanf.c
index 6b4d8c5..9d628b0 100644
--- a/lib/libc/stdio/vfwscanf.c
+++ b/lib/libc/stdio/vfwscanf.c
@@ -138,7 +138,7 @@ static const mbstate_t initial_mbs;
  */
 
 static __inline int
-convert_char(FILE *fp, char * __restrict mbp, int width, locale_t locale)
+convert_char(FILE *fp, char * mbp, int width, locale_t locale)
 {
 	mbstate_t mbs;
 	size_t nconv;
@@ -192,7 +192,7 @@ convert_wchar(FILE *fp, wchar_t *wcp, int width, locale_t locale)
 }
 
 static __inline int
-convert_ccl(FILE *fp, char * __restrict mbp, int width, const struct ccl *ccl,
+convert_ccl(FILE *fp, char * mbp, int width, const struct ccl *ccl,
     locale_t locale)
 {
 	mbstate_t mbs;
@@ -261,7 +261,7 @@ convert_wccl(FILE *fp, wchar_t *wcp, int width, const struct ccl *ccl,
 }
 
 static __inline int
-convert_string(FILE *fp, char * __restrict mbp, int width, locale_t locale)
+convert_string(FILE *fp, char * mbp, int width, locale_t locale)
 {
 	mbstate_t mbs;
 	size_t nconv;
@@ -407,7 +407,7 @@ parseint(FILE *fp, wchar_t *buf, int width, int base, int flags,
 				goto ok;
 			}
 			break;
-					
+
 		/*
 		 * x ok iff flag still set & 2nd char (or 3rd char if
 		 * we have a sign).


More information about the freebsd-current mailing list