All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin Uecker <muecker@gwdg.de>
To: Alejandro Colomar <alx@kernel.org>,
	Xi Ruoyao <xry111@xry111.site>, Jakub Jelinek <jakub@redhat.com>
Cc: <libc-alpha@sourceware.org>, <gcc@gcc.gnu.org>,
	Paul Eggert <eggert@cs.ucla.edu>, <linux-man@vger.kernel.org>
Subject: Re: [PATCH v1] Remove 'restrict' from 'nptr' in strtol(3)-like functions
Date: Fri, 5 Jul 2024 17:02:15 +0200	[thread overview]
Message-ID: <08bc01290aca2408f69a6df2088eed7697968e90.camel@gwdg.de> (raw)
In-Reply-To: <wadzblkwslmjyypxjij4mvt2hy6zihncox5l3mh23vwd7lhmkh@vosxxdjdd53k>

Am Freitag, dem 05.07.2024 um 16:37 +0200 schrieb Alejandro Colomar via Gcc:
> [CC += linux-man@, since we're discussing an API documented there, and
>  the manual page would also need to be updated]
> 
> Hi Xi,  Jakub,
> 
> On Fri, Jul 05, 2024 at 09:38:21PM GMT, Xi Ruoyao wrote:
> > On Fri, 2024-07-05 at 15:03 +0200, Alejandro Colomar wrote:
> > > ISO C specifies these APIs as accepting a restricted pointer in their
> > > first parameter:
> > > 
> > > $ stdc c99 strtol
> > > long int strtol(const char *restrict nptr, char **restrict endptr, int base);
> > > $ stdc c11 strtol
> > > long int strtol(const char *restrict nptr, char **restrict endptr, int base);
> > > 
> > > However, it should be considered a defect in ISO C.  It's common to see
> > > code that aliases it:
> > > 
> > > 	char str[] = "10 20";
> > > 
> > > 	p = str;
> > > 	a = strtol(p, &p, 0);  // Let's ignore error handling for
> > > 	b = strtol(p, &p, 0);  // simplicity.
> > 
> > Why this is wrong?
> > 
> > During the execution of strtol() the only expression accessing the
> > object "p" is *endptr.  When the body of strtol() refers "nptr" it
> > accesses a different object, not "p".
> 
> <http://port70.net/~nsz/c/c11/n1570.html#6.7.3p8>
> 
> Theoretically, 'restrict' is defined in terms of accesses, not just
> references, so it's fine for strtol(3) to hold two references of p in
> restrict pointers.  That is, the following code is valid:
> 
> 	int
> 	dumb(int *restrict a, int *restrict also_a)
> 	{
> 		// We don't access the objects
> 		return a == also_a;
> 	}
> 
> 	int
> 	main(void)
> 	{
> 		int x = 3;
> 
> 		return dumb(&x, &x);
> 	}
> 
> However, in practice that's dumb.  The caller cannot know that the
> function doesn't access the object, so it must be cautious and enable
> -Wrestrict, which should be paranoid and do not allow passing references
> to the same object in different arguments, just in case the function
> decides to access to objects.  Of course, GCC reports a diagnostic for
> the previous code:
> 
> 	$ cc -Wall -Wextra dumb.c 
> 	dumb.c: In function ‘main’:
> 	dumb.c:13:21: warning: passing argument 1 to ‘restrict’-qualified parameter aliases with argument 2 [-Wrestrict]
> 	   13 |         return dumb(&x, &x);
> 	      |                     ^~  ~~
> 
> ... even when there's no UB, since the object is not being accessed.
> 
> But when the thing gets non-trivial, as in strtol(3), GCC misses the
> -Wrestrict diagnostic, as reported in
> <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112833>.
> 
> Let's write a reproducer by altering the dumb.c program from above, with
> just another reference:
> 
> 	int
> 	dumb2(int *restrict a, int *restrict *restrict ap)
> 	{
> 		// We don't access the objects
> 		return a == *ap;
> 	}
> 
> 	int
> 	main(void)
> 	{
> 		int x = 3;
> 		int *xp = &x;
> 
> 		return dumb2(&x, &xp);
> 	}
> 
> GCC doesn't report anything bad here, even though it's basically the
> same as the program from above:
> 
> 	$ cc -Wall -Wextra dumb2.c
> 	$

strtol does have  a "char * restrict * restrict" though, so the
situation is different.   A "char **" and a "const char *"
shouldn't alias anyway. 


> 
> Again, there's no UB, but we really want to be cautious and get a
> diagnostic as callers, just in case the callee decides to access the
> object; we never know.
> 
> So, GCC should be patched to report a warning in the program above.
> That will also cause strtol(3) to start issuing warnings in use cases
> like the one I showed.
> 
> Even further, let's try something really weird: inequality comparison,
> which is only defined for pointers to the same array object:
> 
> 	int
> 	dumb3(int *restrict a, int *restrict *restrict ap)
> 	{
> 		// We don't access the objects
> 		return a > *ap;
> 	}
> 
> 	int
> 	main(void)
> 	{
> 		int x = 3;
> 		int *xp = &x;
> 
> 		return dumb3(&x, &xp);
> 	}
> 
> The behavior is still defined, since the obnjects are not accessed, but
> the compiler should really warn, on both sides:
> 
> -  The caller is passing references to the same object in restricted
>    parameters, which is a red flag.
> 
> -  The callee is comparing for inequality pointers that should, under
>    normal circumstances, cause Undefined Behavior.
> 
> 
> > And if this is really wrong you should report it to WG14 before changing
> > glibc.
> 
> Well, I don't know how to report that defect to WG14.  If you help me,
> I'll be pleased to do so.  Do they have a public mailing list or
> anything like that?

One can submit clarification or change requests:

https://www.open-std.org/jtc1/sc22/wg14/www/contributing.html

Martin



  reply	other threads:[~2024-07-05 15:33 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20240705130249.14116-2-alx@kernel.org>
     [not found] ` <38982a470643f766747b0ca06b27ca859a87b101.camel@xry111.site>
2024-07-05 14:37   ` [PATCH v1] Remove 'restrict' from 'nptr' in strtol(3)-like functions Alejandro Colomar
2024-07-05 15:02     ` Martin Uecker [this message]
2024-07-05 15:23       ` Alejandro Colomar
2024-07-05 15:34         ` Martin Uecker
2024-07-05 15:53           ` Alejandro Colomar
2024-07-05 16:01             ` Xi Ruoyao
2024-07-05 16:17               ` Xi Ruoyao
2024-07-05 16:24               ` Jonathan Wakely
2024-07-05 16:30                 ` Martin Uecker
2024-07-05 19:28                   ` Alejandro Colomar
2024-07-05 19:38                     ` Jonathan Wakely
2024-07-05 19:47                       ` Alejandro Colomar
2024-07-05 19:52                         ` Jonathan Wakely
2024-07-05 20:11                           ` Alejandro Colomar
2024-07-05 20:15                           ` Emanuele Torre
2024-07-05 20:31                             ` Ben Boeckel
2024-07-05 20:25                     ` Martin Uecker
2024-07-05 20:28                       ` Jonathan Wakely
2024-07-05 20:41                         ` Alejandro Colomar
2024-07-05 20:55                         ` Alejandro Colomar
2024-07-05 21:39                           ` Jonathan Wakely
2024-07-05 22:02                             ` Alejandro Colomar
2024-07-05 22:04                               ` Alejandro Colomar
2024-07-06  2:24                               ` Xi Ruoyao
2024-07-06  2:39                                 ` Xi Ruoyao
2024-07-06  5:51                                   ` [[gnu::null_terminated_string_arg(1)]] on strtol(1) (was: [PATCH v1] Remove 'restrict' from 'nptr' in strtol(3)-like) functions Alejandro Colomar
2024-07-06  6:10                                 ` [PATCH v1] Remove 'restrict' from 'nptr' in strtol(3)-like functions Alejandro Colomar
2024-07-06  6:11                                   ` Alejandro Colomar
2024-07-05 16:32                 ` Sam James
2024-07-05 16:02             ` Martin Uecker
2024-07-05 16:11             ` Jonathan Wakely
2024-07-05 16:21               ` Richard Earnshaw (lists)
2024-07-05 15:54         ` LIU Hao
2024-07-05 15:55         ` Xi Ruoyao
2024-07-05 16:32           ` Alejandro Colomar
2024-07-05 17:32             ` Alejandro Colomar
2024-07-05 19:41 ` [WG14] Request for document number; strtol restrictness Alejandro Colomar
2024-07-07 15:46   ` Daniel Plakosh
2024-07-09 19:00     ` Alejandro Colomar
2024-07-09 20:04       ` Daniel Plakosh
2024-07-07  1:58 ` WG14 paper for removing restrict from nptr in strtol(3) Alejandro Colomar
2024-07-07  7:15   ` Martin Uecker
2024-07-07 11:07     ` Alejandro Colomar
2024-07-07 12:21       ` Martin Uecker
2024-07-07 13:10         ` Alejandro Colomar
2024-07-07 10:42   ` Paul Eggert
2024-07-07 12:42     ` Alejandro Colomar
2024-07-07 17:30       ` Paul Eggert
2024-07-07 22:52         ` Alejandro Colomar
2024-07-09 12:09           ` Paul Eggert
2024-07-09 17:36             ` Alejandro Colomar
2024-07-08 14:30       ` David Malcolm
2024-07-08 15:01         ` Alejandro Colomar
2024-07-08 16:05           ` Martin Uecker
2024-07-08 20:17             ` Alejandro Colomar
2024-07-09  5:58               ` Martin Uecker
2024-07-09  9:26                 ` Alejandro Colomar
2024-07-08 22:48           ` David Malcolm
2024-07-09  9:07             ` Alejandro Colomar
2024-07-09  9:18               ` Jakub Jelinek
2024-07-09 10:28                 ` Alejandro Colomar
2024-07-09 11:28                   ` Alejandro Colomar
2024-07-09 22:42   ` n3294 - The restrict function attribute as a replacement of the restrict qualifier Alejandro Colomar
2024-07-26 16:24     ` Joseph Myers
2024-07-26 16:35       ` G. Branden Robinson
2024-07-26 19:53         ` Alejandro Colomar
2024-07-26 18:50       ` Paul Eggert
2024-07-26 20:11       ` Alejandro Colomar
2024-07-26 20:30         ` Joseph Myers
2024-07-26 21:14           ` Alejandro Colomar
2024-07-26 21:22             ` Joseph Myers
2024-07-26 21:49               ` Alejandro Colomar
2024-07-26 22:03                 ` Martin Uecker
2024-07-26 22:26                   ` Alejandro Colomar
2024-07-26 22:59                     ` Martin Uecker
2024-07-27  8:44                       ` Alejandro Colomar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=08bc01290aca2408f69a6df2088eed7697968e90.camel@gwdg.de \
    --to=muecker@gwdg.de \
    --cc=alx@kernel.org \
    --cc=eggert@cs.ucla.edu \
    --cc=gcc@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=libc-alpha@sourceware.org \
    --cc=linux-man@vger.kernel.org \
    --cc=xry111@xry111.site \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.