From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id 4E6BC3858CDB for ; Fri, 19 May 2023 04:13:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4E6BC3858CDB Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=xry111.site Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=xry111.site DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1684469622; bh=iFOCsJYJz7lTBdZ5Dczhf2gdWgGlVf0EHeaMhZ4Glhw=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=hPkH7Ok1FDEzqffUURx/kceDMB7w2yDIlYgD7E0+98kBsV/OlC8IKkBYYCFumv8Yv Jlw2suAGOPOU9OnUkp4OrDc7e7d/APFyt5coQB04jhHXWjmYnjM/cM2TSiwUbTHrCp cF69fHlm0r84S0zDUm/6aZGraxT+6hCzJ6ALIRJ4= Received: from [IPv6:240e:358:11c4:2e00:dc73:854d:832e:5] (unknown [IPv6:240e:358:11c4:2e00:dc73:854d:832e:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id B2582661A4; Fri, 19 May 2023 00:13:37 -0400 (EDT) Message-ID: <528cf363cd06bc0055a4275eda4010ce67c4a4fa.camel@xry111.site> Subject: Re: [PATCH] libio: Add nonnull attribute for most FILE * arguments in stdio.h From: Xi Ruoyao To: Alex Colomar , libc-alpha@sourceware.org Cc: Adhemerval Zanella Netto , Carlos O'Donell Date: Fri, 19 May 2023 12:13:30 +0800 In-Reply-To: References: <20230518172511.2130831-1-xry111@xry111.site> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.48.1 MIME-Version: 1.0 X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00,BODY_8BITS,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,LIKELY_SPAM_FROM,SPF_HELO_PASS,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Thu, 2023-05-18 at 20:29 +0200, Alex Colomar wrote: > On 5/18/23 20:06, Alex Colomar wrote: > > Hi Xi! > >=20 > > On 5/18/23 19:25, Xi Ruoyao via Libc-alpha wrote: > > > During the review of a GCC analyzer test case, we found most stdio > > > functions accepting a FILE * argument expect it to be nonnull and > > > just > > > segfault when the argument is NULL.=C2=A0 Add nonnull attribute for > > > them. > > >=20 > > > setbuf is well defined when __stream is NULL so it's not touched. >=20 > Is this true?=C2=A0 I couldn't find anything about it in either setbuf(3)= , > setbuf(3POSIX), or info libc. >=20 > The buffer can be NULL, but the stream? I guess when I took the note on the paper I misspelled "fflush" as "setbuf" for some reason (maybe lack of coffee :( ). I'll retest all the changes in one hour or two hours. >=20 > > >=20 > > > For fputs, fgets, fread, fwrite, fprintf, vfprintf, and their > > > unlocked > > > version, if __stream is empty but there is nothing to read or > > > write, > > > they don't segfault and I'm not sure if the standard allows such a > > > use > > > so I left them out. > > > --- > > > =C2=A0 libio/stdio.h | 119 ++++++++++++++++++++++++++----------------= -- > > > ------ > > > =C2=A0 1 file changed, 62 insertions(+), 57 deletions(-) > > >=20 > > > diff --git a/libio/stdio.h b/libio/stdio.h > > > index 4cf9f1c012..ae3d7295d4 100644 > > > --- a/libio/stdio.h > > > +++ b/libio/stdio.h > > > @@ -232,7 +232,7 @@ extern char *tempnam (const char *__dir, const > > > char *__pfx) > > > =C2=A0=C2=A0=C2=A0=C2=A0 This function is a possible cancellation poi= nt and therefore > > > not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern int fflush (FILE *__stream); > > > +extern int fflush (FILE *__stream) __nonnull ((1)); > >=20 > > flush(NULL) is well defined.=C2=A0 It flushes all streams that can be > > flushed.=C2=A0 This reminds me that I should document that in the > > SYNOPSIS > > section of the manual page; an oversight on my side. > >=20 > > > =C2=A0 #ifdef __USE_MISC > > > =C2=A0 /* Faster versions when locking is not required. > > > @@ -241,7 +241,7 @@ extern int fflush (FILE *__stream); > > > =C2=A0=C2=A0=C2=A0=C2=A0 cancellation point.=C2=A0 But due to similar= ity with an POSIX > > > interface > > > =C2=A0=C2=A0=C2=A0=C2=A0 or due to the implementation it is a cancell= ation point and > > > =C2=A0=C2=A0=C2=A0=C2=A0 therefore not marked with __THROW.=C2=A0 */ > > > -extern int fflush_unlocked (FILE *__stream); > > > +extern int fflush_unlocked (FILE *__stream) __nonnull ((1)); > >=20 > > Without checking, I'll guess that fflush_unlocked(NULL) is also well > > defined. > >=20 > > I didn't see any other similar cases, but I may have missed some; I > > didn't revise them all thoroughly; please check. > >=20 > > > =C2=A0 #endif > > > =C2=A0 #ifdef __USE_GNU > > > @@ -278,7 +278,7 @@ extern FILE *__REDIRECT (fopen, (const char=20 > > > *__restrict __filename, > > > =C2=A0 extern FILE *__REDIRECT (freopen, (const char *__restrict > > > __filename, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *__restrict = __modes, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 FILE *__restrict __stre= am), freopen64) > > > -=C2=A0 __wur; > > > +=C2=A0 __wur __nonnull ((3)); > > > =C2=A0 # else > > > =C2=A0 #=C2=A0 define fopen fopen64 > > > =C2=A0 #=C2=A0 define freopen freopen64 > > > @@ -335,16 +335,16 @@ extern void setbuf (FILE *__restrict > > > __stream,=20 > > > char *__restrict __buf) __THROW; > > > =C2=A0=C2=A0=C2=A0=C2=A0 If BUF is not NULL, use N bytes of it for bu= ffering; > > > =C2=A0=C2=A0=C2=A0=C2=A0 else allocate an internal buffer N bytes lon= g.=C2=A0 */ > > > =C2=A0 extern int setvbuf (FILE *__restrict __stream, char *__restric= t > > > __buf, > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 i= nt __modes, size_t __n) __THROW; > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 i= nt __modes, size_t __n) __THROW __nonnull ((1)); > > > =C2=A0 #ifdef=C2=A0=C2=A0=C2=A0 __USE_MISC > > > =C2=A0 /* If BUF is NULL, make STREAM unbuffered. > > > =C2=A0=C2=A0=C2=A0=C2=A0 Else make it use SIZE bytes of BUF for buffe= ring.=C2=A0 */ > > > =C2=A0 extern void setbuffer (FILE *__restrict __stream, char > > > *__restrict=20 > > > __buf, > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 size_t __size) __THROW; > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 size_t __size) __THROW __nonnull ((1)); > > > =C2=A0 /* Make STREAM line-buffered.=C2=A0 */ > > > -extern void setlinebuf (FILE *__stream) __THROW; > > > +extern void setlinebuf (FILE *__stream) __THROW __nonnull ((1)); > > > =C2=A0 #endif > > > @@ -418,7 +418,7 @@ extern int dprintf (int __fd, const char=20 > > > *__restrict __fmt, ...) > > > =C2=A0=C2=A0=C2=A0=C2=A0 This function is a possible cancellation poi= nt and therefore > > > not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > =C2=A0 extern int fscanf (FILE *__restrict __stream, > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const c= har *__restrict __format, ...) __wur; > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const c= har *__restrict __format, ...) __wur __nonnull > > > ((1)); > > > =C2=A0 /* Read formatted input from stdin. > > > =C2=A0=C2=A0=C2=A0=C2=A0 This function is a possible cancellation poi= nt and therefore > > > not > > > @@ -439,7 +439,7 @@ extern int sscanf (const char *__restrict __s, > > > =C2=A0 #=C2=A0 ifdef __REDIRECT > > > =C2=A0 extern int __REDIRECT (fscanf, (FILE *__restrict __stream, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *__restrict __format, ...), > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 __isoc23_fscanf) __wur; > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 __isoc23_fscanf) __wur __nonnull ((1)); > > > =C2=A0 extern int __REDIRECT (scanf, (const char *__restrict __format= , > > > ...), > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 __isoc23_scanf) __wur; > > > =C2=A0 extern int __REDIRECT_NTH (sscanf, (const char *__restrict __s= , > > > @@ -447,7 +447,7 @@ extern int __REDIRECT_NTH (sscanf, (const char > > > *__restrict __s, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 __isoc23_sscanf); > > > =C2=A0 #=C2=A0 else > > > =C2=A0 extern int __isoc23_fscanf (FILE *__restrict __stream, > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 const char *__restrict __format, ...) __wur; > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 const char *__restrict __format, ...) __wur > > > __nonnull=20 > > > ((1)); > > > =C2=A0 extern int __isoc23_scanf (const char *__restrict __format, ..= .) > > > __wur; > > > =C2=A0 extern int __isoc23_sscanf (const char *__restrict __s, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *__restrict __format, ...) __T= HROW; > > > @@ -459,7 +459,7 @@ extern int __isoc23_sscanf (const char > > > *__restrict=20 > > > __s, > > > =C2=A0 #=C2=A0 ifdef __REDIRECT > > > =C2=A0 extern int __REDIRECT (fscanf, (FILE *__restrict __stream, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *__restrict __format, ...), > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 __isoc99_fscanf) __wur; > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 __isoc99_fscanf) __wur __nonnull ((1)); > > > =C2=A0 extern int __REDIRECT (scanf, (const char *__restrict __format= , > > > ...), > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 __isoc99_scanf) __wur; > > > =C2=A0 extern int __REDIRECT_NTH (sscanf, (const char *__restrict __s= , > > > @@ -467,7 +467,7 @@ extern int __REDIRECT_NTH (sscanf, (const char > > > *__restrict __s, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 __isoc99_sscanf); > > > =C2=A0 #=C2=A0 else > > > =C2=A0 extern int __isoc99_fscanf (FILE *__restrict __stream, > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 const char *__restrict __format, ...) __wur; > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 const char *__restrict __format, ...) __wur > > > __nonnull=20 > > > ((1)); > > > =C2=A0 extern int __isoc99_scanf (const char *__restrict __format, ..= .) > > > __wur; > > > =C2=A0 extern int __isoc99_sscanf (const char *__restrict __s, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *__restrict __format, ...) __T= HROW; > > > @@ -485,7 +485,7 @@ extern int __isoc99_sscanf (const char > > > *__restrict=20 > > > __s, > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > =C2=A0 extern int vfscanf (FILE *__restrict __s, const char *__restri= ct > > > __format, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 __gnuc_va_list __arg) > > > -=C2=A0=C2=A0=C2=A0=C2=A0 __attribute__ ((__format__ (__scanf__, 2, 0= ))) __wur; > > > +=C2=A0=C2=A0=C2=A0=C2=A0 __attribute__ ((__format__ (__scanf__, 2, 0= ))) __wur > > > __nonnull=20 > > > ((1)); > > > =C2=A0 /* Read formatted input from stdin into argument list ARG. > > > @@ -508,7 +508,7 @@ extern int __REDIRECT (vfscanf, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 (FILE *__restrict __s, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 const char *__restrict __format, __gnuc_va_list > > > __arg), > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 __isoc23_vfscanf) > > > -=C2=A0=C2=A0=C2=A0=C2=A0 __attribute__ ((__format__ (__scanf__, 2, 0= ))) __wur; > > > +=C2=A0=C2=A0=C2=A0=C2=A0 __attribute__ ((__format__ (__scanf__, 2, 0= ))) __wur > > > __nonnull=20 > > > ((1)); > > > =C2=A0 extern int __REDIRECT (vscanf, (const char *__restrict __forma= t, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __gnuc_va_list __arg), __isoc23_vscanf) > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __attribute__ ((__format__ (__sc= anf__, 1, 0))) __wur; > > > @@ -520,7 +520,7 @@ extern int __REDIRECT_NTH (vsscanf, > > > =C2=A0 #=C2=A0=C2=A0 elif !defined __REDIRECT > > > =C2=A0 extern int __isoc23_vfscanf (FILE *__restrict __s, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *__restrict __format, > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __gnuc_va_list __arg) __wur; > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __gnuc_va_list __arg) __wur __nonnull ((1)); > > > =C2=A0 extern int __isoc23_vscanf (const char *__restrict __format, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __gnuc_va_list __arg) __wur; > > > =C2=A0 extern int __isoc23_vsscanf (const char *__restrict __s, > > > @@ -537,7 +537,7 @@ extern int __REDIRECT (vfscanf, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 (FILE *__restrict __s, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 const char *__restrict __format, __gnuc_va_list > > > __arg), > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 __isoc99_vfscanf) > > > -=C2=A0=C2=A0=C2=A0=C2=A0 __attribute__ ((__format__ (__scanf__, 2, 0= ))) __wur; > > > +=C2=A0=C2=A0=C2=A0=C2=A0 __attribute__ ((__format__ (__scanf__, 2, 0= ))) __wur > > > __nonnull=20 > > > ((1)); > > > =C2=A0 extern int __REDIRECT (vscanf, (const char *__restrict __forma= t, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __gnuc_va_list __arg), __isoc99_vscanf) > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __attribute__ ((__format__ (__sc= anf__, 1, 0))) __wur; > > > @@ -549,7 +549,7 @@ extern int __REDIRECT_NTH (vsscanf, > > > =C2=A0 #=C2=A0=C2=A0 elif !defined __REDIRECT > > > =C2=A0 extern int __isoc99_vfscanf (FILE *__restrict __s, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *__restrict __format, > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __gnuc_va_list __arg) __wur; > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __gnuc_va_list __arg) __wur __nonnull ((1)); > > > =C2=A0 extern int __isoc99_vscanf (const char *__restrict __format, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __gnuc_va_list __arg) __wur; > > > =C2=A0 extern int __isoc99_vsscanf (const char *__restrict __s, > > > @@ -568,8 +568,8 @@ extern int __isoc99_vsscanf (const char=20 > > > *__restrict __s, > > > =C2=A0=C2=A0=C2=A0=C2=A0 These functions are possible cancellation po= ints and > > > therefore not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern int fgetc (FILE *__stream); > > > -extern int getc (FILE *__stream); > > > +extern int fgetc (FILE *__stream) __nonnull ((1)); > > > +extern int getc (FILE *__stream) __nonnull ((1)); > > > =C2=A0 /* Read a character from stdin. > > > @@ -582,7 +582,7 @@ extern int getchar (void); > > > =C2=A0=C2=A0=C2=A0=C2=A0 These functions are possible cancellation po= ints and > > > therefore not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern int getc_unlocked (FILE *__stream); > > > +extern int getc_unlocked (FILE *__stream) __nonnull ((1)); > > > =C2=A0 extern int getchar_unlocked (void); > > > =C2=A0 #endif /* Use POSIX.=C2=A0 */ > > > @@ -593,7 +593,7 @@ extern int getchar_unlocked (void); > > > =C2=A0=C2=A0=C2=A0=C2=A0 cancellation point.=C2=A0 But due to similar= ity with an POSIX > > > interface > > > =C2=A0=C2=A0=C2=A0=C2=A0 or due to the implementation it is a cancell= ation point and > > > =C2=A0=C2=A0=C2=A0=C2=A0 therefore not marked with __THROW.=C2=A0 */ > > > -extern int fgetc_unlocked (FILE *__stream); > > > +extern int fgetc_unlocked (FILE *__stream) __nonnull ((1)); > > > =C2=A0 #endif /* Use MISC.=C2=A0 */ > > > @@ -604,8 +604,8 @@ extern int fgetc_unlocked (FILE *__stream); > > > =C2=A0=C2=A0=C2=A0=C2=A0 These functions is a possible cancellation p= oint and > > > therefore not > >=20 > > Aside: here's a typo mixing plural and singular in the sentence (not > > part of your commit).=C2=A0 I'll prepare a patch for it. > >=20 > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern int fputc (int __c, FILE *__stream); > > > -extern int putc (int __c, FILE *__stream); > > > +extern int fputc (int __c, FILE *__stream) __nonnull ((2)); > > > +extern int putc (int __c, FILE *__stream) __nonnull ((2)); > > > =C2=A0 /* Write a character to stdout. > > > @@ -620,7 +620,7 @@ extern int putchar (int __c); > > > =C2=A0=C2=A0=C2=A0=C2=A0 cancellation point.=C2=A0 But due to similar= ity with an POSIX > > > interface > > > =C2=A0=C2=A0=C2=A0=C2=A0 or due to the implementation it is a cancell= ation point and > > > =C2=A0=C2=A0=C2=A0=C2=A0 therefore not marked with __THROW.=C2=A0 */ > > > -extern int fputc_unlocked (int __c, FILE *__stream); > > > +extern int fputc_unlocked (int __c, FILE *__stream) __nonnull > > > ((2)); > > > =C2=A0 #endif /* Use MISC.=C2=A0 */ > > > =C2=A0 #ifdef __USE_POSIX199506 > > > @@ -628,7 +628,7 @@ extern int fputc_unlocked (int __c, FILE > > > *__stream); > > > =C2=A0=C2=A0=C2=A0=C2=A0 These functions are possible cancellation po= ints and > > > therefore not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern int putc_unlocked (int __c, FILE *__stream); > > > +extern int putc_unlocked (int __c, FILE *__stream) __nonnull > > > ((2)); > > > =C2=A0 extern int putchar_unlocked (int __c); > > > =C2=A0 #endif /* Use POSIX.=C2=A0 */ > > > @@ -636,10 +636,10 @@ extern int putchar_unlocked (int __c); > > > =C2=A0 #if defined __USE_MISC \ > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 || (defined __USE_XOPEN && !defined __= USE_XOPEN2K) > > > =C2=A0 /* Get a word (int) from STREAM.=C2=A0 */ > > > -extern int getw (FILE *__stream); > > > +extern int getw (FILE *__stream) __nonnull ((1)); > > > =C2=A0 /* Write a word (int) to STREAM.=C2=A0 */ > > > -extern int putw (int __w, FILE *__stream); > > > +extern int putw (int __w, FILE *__stream) __nonnull ((2)); > > > =C2=A0 #endif > > > @@ -689,10 +689,10 @@ extern char *fgets_unlocked (char > > > *__restrict=20 > > > __s, int __n, > > > =C2=A0=C2=A0=C2=A0=C2=A0 therefore not marked with __THROW.=C2=A0 */ > > > =C2=A0 extern __ssize_t __getdelim (char **__restrict __lineptr, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 size_t *__restrict __n, int > > > __delimiter, > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 FILE *__restrict __stream) __wur; > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 FILE *__restrict __stream) __wur=20 > > > __nonnull ((4)); > > > =C2=A0 extern __ssize_t getdelim (char **__restrict __lineptr, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 size_t *__restrict __n, int > > > __delimiter, > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 FILE *__restrict __stream) __wur; > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 FILE *__restrict __stream) __wur > > > __nonnull=20 > > > ((4)); > > > =C2=A0 /* Like `getdelim', but reads up to a newline. > > > @@ -702,7 +702,7 @@ extern __ssize_t getdelim (char **__restrict=20 > > > __lineptr, > > > =C2=A0=C2=A0=C2=A0=C2=A0 therefore not marked with __THROW.=C2=A0 */ > > > =C2=A0 extern __ssize_t getline (char **__restrict __lineptr, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 size_t *__restrict __n, > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 FILE *__restrict __stream) __wur; > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 FILE *__restrict __stream) __wur > > > __nonnull=20 > > > ((3)); > > > =C2=A0 #endif > > > @@ -723,7 +723,7 @@ extern int puts (const char *__s); > > > =C2=A0=C2=A0=C2=A0=C2=A0 This function is a possible cancellation poi= nt and therefore > > > not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern int ungetc (int __c, FILE *__stream); > > > +extern int ungetc (int __c, FILE *__stream) __nonnull ((2)); > > > =C2=A0 /* Read chunks of generic data from STREAM. > > > @@ -768,17 +768,17 @@ extern size_t fwrite_unlocked (const void=20 > > > *__restrict __ptr, size_t __size, > > > =C2=A0=C2=A0=C2=A0=C2=A0 This function is a possible cancellation poi= nt and therefore > > > not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern int fseek (FILE *__stream, long int __off, int __whence); > > > +extern int fseek (FILE *__stream, long int __off, int __whence)=20 > > > __nonnull ((1)); > > > =C2=A0 /* Return the current position of STREAM. > > > =C2=A0=C2=A0=C2=A0=C2=A0 This function is a possible cancellation poi= nt and therefore > > > not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern long int ftell (FILE *__stream) __wur; > > > +extern long int ftell (FILE *__stream) __wur __nonnull ((1)); > > > =C2=A0 /* Rewind to the beginning of STREAM. > > > =C2=A0=C2=A0=C2=A0=C2=A0 This function is a possible cancellation poi= nt and therefore > > > not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern void rewind (FILE *__stream); > > > +extern void rewind (FILE *__stream) __nonnull ((1)); > > > =C2=A0 /* The Single Unix Specification, Version 2, specifies an > > > alternative, > > > =C2=A0=C2=A0=C2=A0=C2=A0 more adequate interface for the two function= s above which > > > deal with > > > @@ -791,18 +791,19 @@ extern void rewind (FILE *__stream); > > > =C2=A0=C2=A0=C2=A0=C2=A0 This function is a possible cancellation poi= nt and therefore > > > not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern int fseeko (FILE *__stream, __off_t __off, int __whence); > > > +extern int fseeko (FILE *__stream, __off_t __off, int __whence)=20 > > > __nonnull ((1)); > > > =C2=A0 /* Return the current position of STREAM. > > > =C2=A0=C2=A0=C2=A0=C2=A0 This function is a possible cancellation poi= nt and therefore > > > not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern __off_t ftello (FILE *__stream) __wur; > > > +extern __off_t ftello (FILE *__stream) __wur __nonnull ((1)); > > > =C2=A0 # else > > > =C2=A0 #=C2=A0 ifdef __REDIRECT > > > =C2=A0 extern int __REDIRECT (fseeko, > > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 (FILE *__stream, __off64_t __off, int __whence)= , > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 fseeko64); > > > -extern __off64_t __REDIRECT (ftello, (FILE *__stream), ftello64); > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 fseeko64) __nonnull ((1)); > > > +extern __off64_t __REDIRECT (ftello, (FILE *__stream), ftello64) > > > +=C2=A0 __nonnull ((1)); > > > =C2=A0 #=C2=A0 else > > > =C2=A0 #=C2=A0=C2=A0 define fseeko fseeko64 > > > =C2=A0 #=C2=A0=C2=A0 define ftello ftello64 > > > @@ -815,18 +816,20 @@ extern __off64_t __REDIRECT (ftello, (FILE=20 > > > *__stream), ftello64); > > > =C2=A0=C2=A0=C2=A0=C2=A0 This function is a possible cancellation poi= nt and therefore > > > not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict > > > __pos); > > > +extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict > > > __pos) > > > +=C2=A0 __nonnull ((1)); > > > =C2=A0 /* Set STREAM's position. > > > =C2=A0=C2=A0=C2=A0=C2=A0 This function is a possible cancellation poi= nt and therefore > > > not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern int fsetpos (FILE *__stream, const fpos_t *__pos); > > > +extern int fsetpos (FILE *__stream, const fpos_t *__pos) > > > __nonnull=20 > > > ((1)); > > > =C2=A0 #else > > > =C2=A0 # ifdef __REDIRECT > > > =C2=A0 extern int __REDIRECT (fgetpos, (FILE *__restrict __stream, > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 fpos_t *__restrict __pos), fgetpos64); > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 fpos_t *__restrict __pos), fgetpos64) __nonn= ull > > > ((1)); > > > =C2=A0 extern int __REDIRECT (fsetpos, > > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 (FILE *__stream, const fpos_t *__pos), fsetpos64); > > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 (FILE *__stream, const fpos_t *__pos), fsetpos64) > > > +=C2=A0 __nonnull ((1)); > > > =C2=A0 # else > > > =C2=A0 #=C2=A0 define fgetpos fgetpos64 > > > =C2=A0 #=C2=A0 define fsetpos fsetpos64 > > > @@ -834,24 +837,26 @@ extern int __REDIRECT (fsetpos, > > > =C2=A0 #endif > > > =C2=A0 #ifdef __USE_LARGEFILE64 > > > -extern int fseeko64 (FILE *__stream, __off64_t __off, int > > > __whence); > > > -extern __off64_t ftello64 (FILE *__stream) __wur; > > > -extern int fgetpos64 (FILE *__restrict __stream, fpos64_t > > > *__restrict=20 > > > __pos); > > > -extern int fsetpos64 (FILE *__stream, const fpos64_t *__pos); > > > +extern int fseeko64 (FILE *__stream, __off64_t __off, int > > > __whence) > > > +=C2=A0 __nonnull ((1)); > > > +extern __off64_t ftello64 (FILE *__stream) __wur __nonnull ((1)); > > > +extern int fgetpos64 (FILE *__restrict __stream, fpos64_t > > > *__restrict=20 > > > __pos) > > > +=C2=A0 __nonnull ((1)); > > > +extern int fsetpos64 (FILE *__stream, const fpos64_t *__pos)=20 > > > __nonnull ((1)); > > > =C2=A0 #endif > > > =C2=A0 /* Clear the error and EOF indicators for STREAM.=C2=A0 */ > > > -extern void clearerr (FILE *__stream) __THROW; > > > +extern void clearerr (FILE *__stream) __THROW __nonnull ((1)); > > > =C2=A0 /* Return the EOF indicator for STREAM.=C2=A0 */ > > > -extern int feof (FILE *__stream) __THROW __wur; > > > +extern int feof (FILE *__stream) __THROW __wur __nonnull ((1)); > > > =C2=A0 /* Return the error indicator for STREAM.=C2=A0 */ > > > -extern int ferror (FILE *__stream) __THROW __wur; > > > +extern int ferror (FILE *__stream) __THROW __wur __nonnull ((1)); > > > =C2=A0 #ifdef __USE_MISC > > > =C2=A0 /* Faster versions when locking is not required.=C2=A0 */ > > > -extern void clearerr_unlocked (FILE *__stream) __THROW; > > > -extern int feof_unlocked (FILE *__stream) __THROW __wur; > > > -extern int ferror_unlocked (FILE *__stream) __THROW __wur; > > > +extern void clearerr_unlocked (FILE *__stream) __THROW __nonnull > > > ((1)); > > > +extern int feof_unlocked (FILE *__stream) __THROW __wur __nonnull > > > ((1)); > > > +extern int ferror_unlocked (FILE *__stream) __THROW __wur > > > __nonnull=20 > > > ((1)); > > > =C2=A0 #endif > > > @@ -864,12 +869,12 @@ extern void perror (const char *__s) __COLD; > > > =C2=A0 #ifdef=C2=A0=C2=A0=C2=A0 __USE_POSIX > > > =C2=A0 /* Return the system file descriptor for STREAM.=C2=A0 */ > > > -extern int fileno (FILE *__stream) __THROW __wur; > > > +extern int fileno (FILE *__stream) __THROW __wur __nonnull ((1)); > > > =C2=A0 #endif /* Use POSIX.=C2=A0 */ > > > =C2=A0 #ifdef __USE_MISC > > > =C2=A0 /* Faster version when locking is not required.=C2=A0 */ > > > -extern int fileno_unlocked (FILE *__stream) __THROW __wur; > > > +extern int fileno_unlocked (FILE *__stream) __THROW __wur > > > __nonnull=20 > > > ((1)); > > > =C2=A0 #endif > > > @@ -878,7 +883,7 @@ extern int fileno_unlocked (FILE *__stream)=20 > > > __THROW __wur; > > > =C2=A0=C2=A0=C2=A0=C2=A0 This function is a possible cancellation poi= nt and therefore > > > not > > > =C2=A0=C2=A0=C2=A0=C2=A0 marked with __THROW.=C2=A0 */ > > > -extern int pclose (FILE *__stream); > > > +extern int pclose (FILE *__stream) __nonnull ((1)); > >=20 > > You didn't patch fclose(3).=C2=A0 Any reason?=C2=A0 I guess it's simila= rly UB > > to > > call fclose(NULL). > >=20 > > Cheers, > > Alex > >=20 > > > =C2=A0 /* Create a new stream connected to a pipe running the given > > > command. > > > @@ -922,14 +927,14 @@ extern int obstack_vprintf (struct obstack=20 > > > *__restrict __obstack, > > > =C2=A0 /* These are defined in POSIX.1:1996.=C2=A0 */ > > > =C2=A0 /* Acquire ownership of STREAM.=C2=A0 */ > > > -extern void flockfile (FILE *__stream) __THROW; > > > +extern void flockfile (FILE *__stream) __THROW __nonnull ((1)); > > > =C2=A0 /* Try to acquire ownership of STREAM but do not block if it i= s > > > not > > > =C2=A0=C2=A0=C2=A0=C2=A0 possible.=C2=A0 */ > > > -extern int ftrylockfile (FILE *__stream) __THROW __wur; > > > +extern int ftrylockfile (FILE *__stream) __THROW __wur __nonnull > > > ((1)); > > > =C2=A0 /* Relinquish the ownership granted for STREAM.=C2=A0 */ > > > -extern void funlockfile (FILE *__stream) __THROW; > > > +extern void funlockfile (FILE *__stream) __THROW __nonnull ((1)); > > > =C2=A0 #endif /* POSIX */ > > > =C2=A0 #if defined __USE_XOPEN && !defined __USE_XOPEN2K && !defined > > > __USE_GNU > >=20 >=20 > --=20 > > GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5 >=20 --=20 Xi Ruoyao School of Aerospace Science and Technology, Xidian University