Re: [PATCH v1] Remove 'restrict' from 'nptr' in strtol(3)-like functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jul 05, 2024 at 06:32:26PM GMT, Alejandro Colomar wrote:
> Hi Xi,
> 
> On Fri, Jul 05, 2024 at 11:55:05PM GMT, Xi Ruoyao wrote:
> > On Fri, 2024-07-05 at 17:23 +0200, Alejandro Colomar wrote:
> > > > strtol does have  a "char * restrict * restrict" though, so the
> > > > situation is different.   A "char **" and a "const char *"
> > > > shouldn't alias anyway. 
> > > 
> > > Pedantically, it is actually declared as 'char **restrict' (the inner
> > > one is not declared as restrict, even though it will be restricted,
> > > since there are no other unrestricted pointers).
> > 
> > So how's the following implementation of strtol (10-based, no negative
> > number handling, no overflow handling, ASCII-only) wrong?
> > 
> > long int my_strtol(const char *restrict nptr, char **restrict endptr)
> > {
> >   long ret = 0;
> > 
> >   while (isdigit(*nptr))
> >     ret = ret * 10 + (*nptr++ - '0');
> > 
> >   *endptr = (char *)nptr;
> >   return ret;
> > }
> > 
> > There's no dumb thing, there's no restrict violation (unless it's called
> > in a stupid way, see below), and there **shouldn't** be a -Wrestrict
> > warning.
> > 
> > If you do
> > 
> > char *x = NULL;
> > strtol((char *)&x, &x, 10);
> 
> The restrict in `char **restrict endptr` already protects you from this.
> You don't need to make the first parameter also restricted.  See:
> 
> 	$ cat r.c 
> 	long alx_strtol(const char *nptr, char **restrict endp);
> 
> 	int main(void)
> 	{
> 		char x = 3;
> 		char *xp = &x;
> 
> 		alx_strtol(xp, &xp);  // Fine.
> 		alx_strtol(xp, (char **) xp);  // Bug.
> 		alx_strtol((char *) &xp, &xp);  // Bug.
> 	}
> 	$ cc -Wall -Wextra -S r.c 
> 	r.c: In function ‘main’:
> 	r.c:9:24: warning: passing argument 2 to ‘restrict’-qualified parameter aliases with argument 1 [-Wrestrict]
> 	    9 |         alx_strtol(xp, (char **) xp);  // Bug.
> 	      |                        ^~~~~~~~~~~~
> 	r.c:10:34: warning: passing argument 2 to ‘restrict’-qualified parameter aliases with argument 1 [-Wrestrict]
> 	   10 |         alx_strtol((char *) &xp, &xp);  // Bug.
> 	      |                    ~~~~~~~~~~~~  ^~~
> 
> Using my proposed prototype wouldn't case any warnings with a powerful
> -fanalyzer that would be able to emit diagnostics with the current
> prototype.
> 
> In strtol(3), there are 3 pointers:
> 
> -  nptr
> -  *endptr
> -  endptr
> 
> The first two should be allowed to alias each other (and at the end of
> the call, they definitely alias each other).  It is only the third one
> which must not alias any of the other, which is why my patch (v2) keeps

(Whoops; forget about that v2; that was about a similar patch to
strsep(3).  In this case we're in patch v1; which already had that into
consideration.  Please read it as s/v2/v1/.)

> that restrict, but removes the other one.
> 
> Does that make sense?
> 
> Cheers,
> Alex
> 
> > 
> > it'll violate restrict.  Nobody sane should write this, and it's warned
> > anyway:
> > 
> > t.c: In function 'main':
> > t.c:6:28: warning: passing argument 2 to 'restrict'-qualified parameter
> > aliases with argument 1 [-Wrestrict]
> >     6 |         strtol((char *)&x, &x, 10);
> >       |                ~~~~~~~~~~  ^~
> > 
> > -- 
> > Xi Ruoyao <xry111@xxxxxxxxxxx>
> > School of Aerospace Science and Technology, Xidian University
> 
> -- 
> <https://www.alejandro-colomar.es/>



-- 
<https://www.alejandro-colomar.es/>

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux