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

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

 



Hi Jonathan,

On Fri, Jul 05, 2024 at 08:52:30PM GMT, Jonathan Wakely wrote:
> > > > > > > It **shouldn't**.  strtol will only violate restrict if it's wrongly
> > > > > > > implemented, or something dumb is done like "strtol((const char*) &p,
> > > > > > > &p, 0)".
> > > > > > >
> > > > > > > See my previous reply.
> > > >
> > > > That's not right.  See my reply to yours, Xi.  The restrict in
> > > >
> > > >         char **endptr
> > > >
> > > > already prevents calls such as strtol(x, x, 0).
> > >
> > > That seems to contradict footnote 153 in C23.
> >
> > Did you mean a different footnote number?
> 
> No.
> 
> >
> > Here's 153 in N3047:
> 
> That draft is nearly two years old.
> 
> >
> > 153) An implementation can delay the choice of which integer type until
> >      all enumeration constants have been seen.
> >
> > which seems completely unrelated.
> 
> Because you're looking at a draft from nearly two years ago. Try N3220.

Ahhh, sorry!  Indeed.

Let's quote it here, for others to not need to find it:

153) In other words, E depends on the value of P itself rather than on
     the value of an object referenced indirectly through P.  For
     example, if identifier p has type (int **restrict), then the
     pointer expressions p and p+1 are based on the restricted pointer
     object designated by p, but the pointer expressions *p and p[1] are
     not.

I don't think footnote 153 is problematic here.

Let's have this prototype:

	long int
	alx_strtol(const char *nptr, char **restrict endptr, int base);

and let's discuss some example of bad usage:

	char str[] = "1";

	s = str;
	alx_strtol(s, (char **)s, 0);

According to 153, the pointer expression endptr is based on the
restricted pointer object, but *endptr and nptr are not.

The user has passed s as endptr, and also s as nptr.  Thus, the object
s is being accessed via a restricted pointer, endptr, and a
non-restricted one, nptr.  That's UB.

Let's see a different example of bad usage:

	char str[] = "1";

	s = str;
	alx_strtol((char *)&s, &s, 0);

For similar reasons, it's also UB.

The compiler diagnoses both:

	$ cat r.c
	long alx_strtol(const char *s, char **restrict endp, int base);

	int main(void)
	{
		char x = 3;
		char *xp = &x;

		alx_strtol(xp, &xp, 0);  // Fine.
		alx_strtol(xp, (char **) xp, 0);  // Bug.
		alx_strtol((char *) &xp, &xp, 0);  // 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, 0);  // Bug.
	      |                        ^~~~~~~~~~~~
	r.c:10:34: warning: passing argument 2 to ‘restrict’-qualified parameter aliases with argument 1 [-Wrestrict]
	   10 |         alx_strtol((char *) &xp, &xp, 0);  // Bug.
	      |                    ~~~~~~~~~~~~  ^~~

Cheers,
Alex

-- 
<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