public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* Bad interaction between signal constants and -Wsign-conversion
@ 2023-03-28  1:23 Zack Weinberg
  2023-03-28  1:58 ` Paul Eggert
  2023-03-29  0:08 ` Alejandro Colomar
  0 siblings, 2 replies; 11+ messages in thread
From: Zack Weinberg @ 2023-03-28  1:23 UTC (permalink / raw)
  To: GNU libc development

This test program does something perfectly normal.  Well, it's cut down
from a program that does something perfectly normal.  SA_RESETHAND is
one of the bit flags intended to be used with the sa_flags field of
struct sigaction.

#include <signal.h>

struct sigaction sa = { 
  .sa_flags = SA_RESETHAND,
};

However ... on Linux, SA_RESETHAND happens to have the value 0x80000000,
and therefore, the type of that constant is 'unsigned int'.  And the
type of sa_flags is 'int'.  So if you compile this test program with
-Wconversion you get a warning:

$ gcc -fsyntax-only -Wconversion test.c
test.c:4:15: warning: signed conversion from ‘unsigned int’ to ‘int’
   changes value from ‘2147483648’ to ‘-2147483648’ [-Wsign-conversion]
    4 |  .sa_flags = SA_RESETHAND,
      |              ^~~~~~~~~~~~

This strikes me as a (minor) bug in our headers.  Given the ABI constraints
(this is a flags word passed to the kernel), I think the most straightforward
fix is probably to change the #define in bits/sigaction.h to

# define SA_RESETHAND ((int)0x80000000) /* Reset to SIG_DFL on entry to handler.  */

Anyone got a better idea?

zw

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Bad interaction between signal constants and -Wsign-conversion
  2023-03-28  1:23 Bad interaction between signal constants and -Wsign-conversion Zack Weinberg
@ 2023-03-28  1:58 ` Paul Eggert
  2023-03-28 14:03   ` Cyril Hrubis
  2023-03-29  0:08 ` Alejandro Colomar
  1 sibling, 1 reply; 11+ messages in thread
From: Paul Eggert @ 2023-03-28  1:58 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: GNU libc development

On 3/27/23 18:23, Zack Weinberg via Libc-alpha wrote:
> # define SA_RESETHAND ((int)0x80000000) /* Reset to SIG_DFL on entry to handler.  */
> 
> Anyone got a better idea?

Perhaps this instead:

   #define SA_RESETHAND (-1 - 0x7fffffff)

so that it is usable in preprocessor expressions. This is the sort of 
thing that <limits.h> does for INT_MIN, and what 
glibc/sysdeps/sparc/fpu/bits/fenv.h does for FE_UPWARD.

Are there other instances of 0x80000000 in user-visible glibc headers 
that could cause similar problems?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Bad interaction between signal constants and -Wsign-conversion
  2023-03-28  1:58 ` Paul Eggert
@ 2023-03-28 14:03   ` Cyril Hrubis
  2023-03-28 14:53     ` Florian Weimer
  0 siblings, 1 reply; 11+ messages in thread
From: Cyril Hrubis @ 2023-03-28 14:03 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Zack Weinberg, GNU libc development

Hi!
> > # define SA_RESETHAND ((int)0x80000000) /* Reset to SIG_DFL on entry to handler.  */
> > 
> > Anyone got a better idea?
> 
> Perhaps this instead:
> 
>    #define SA_RESETHAND (-1 - 0x7fffffff)

Why not (1<<31) ?

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Bad interaction between signal constants and -Wsign-conversion
  2023-03-28 14:03   ` Cyril Hrubis
@ 2023-03-28 14:53     ` Florian Weimer
  2023-03-28 15:04       ` Andreas Schwab
  0 siblings, 1 reply; 11+ messages in thread
From: Florian Weimer @ 2023-03-28 14:53 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: Paul Eggert, Zack Weinberg, GNU libc development

* Cyril Hrubis:

> Hi!
>> > # define SA_RESETHAND ((int)0x80000000) /* Reset to SIG_DFL on entry to handler.  */
>> > 
>> > Anyone got a better idea?
>> 
>> Perhaps this instead:
>> 
>>    #define SA_RESETHAND (-1 - 0x7fffffff)
>
> Why not (1<<31) ?

Some compilers warn about it, too.  Shifting into the sign position is
undefined in the standard.

I suggest to write out the negative constants explicitly, as a decimal
integer.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Bad interaction between signal constants and -Wsign-conversion
  2023-03-28 14:53     ` Florian Weimer
@ 2023-03-28 15:04       ` Andreas Schwab
  2023-03-28 18:50         ` Florian Weimer
  0 siblings, 1 reply; 11+ messages in thread
From: Andreas Schwab @ 2023-03-28 15:04 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Cyril Hrubis, Paul Eggert, Zack Weinberg, GNU libc development

On Mär 28 2023, Florian Weimer wrote:

> I suggest to write out the negative constants explicitly, as a decimal
> integer.

That doesn't work either, because you cannot write a negative literal.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Bad interaction between signal constants and -Wsign-conversion
  2023-03-28 15:04       ` Andreas Schwab
@ 2023-03-28 18:50         ` Florian Weimer
  0 siblings, 0 replies; 11+ messages in thread
From: Florian Weimer @ 2023-03-28 18:50 UTC (permalink / raw)
  To: Andreas Schwab via Libc-alpha
  Cc: Andreas Schwab, Cyril Hrubis, Paul Eggert, Zack Weinberg

* Andreas Schwab via Libc-alpha:

> On Mär 28 2023, Florian Weimer wrote:
>
>> I suggest to write out the negative constants explicitly, as a decimal
>> integer.
>
> That doesn't work either, because you cannot write a negative literal.

Oh.  Yes, then the more complicated expression is actually needed.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Bad interaction between signal constants and -Wsign-conversion
  2023-03-28  1:23 Bad interaction between signal constants and -Wsign-conversion Zack Weinberg
  2023-03-28  1:58 ` Paul Eggert
@ 2023-03-29  0:08 ` Alejandro Colomar
  2023-03-30 13:45   ` Zack Weinberg
  2023-03-30 13:59   ` Vincent Lefevre
  1 sibling, 2 replies; 11+ messages in thread
From: Alejandro Colomar @ 2023-03-29  0:08 UTC (permalink / raw)
  To: Zack Weinberg, GNU libc development


[-- Attachment #1.1: Type: text/plain, Size: 2156 bytes --]

Hi Zack,

On 3/28/23 03:23, Zack Weinberg via Libc-alpha wrote:
> This test program does something perfectly normal.  Well, it's cut down
> from a program that does something perfectly normal.  SA_RESETHAND is
> one of the bit flags intended to be used with the sa_flags field of
> struct sigaction.
> 
> #include <signal.h>
> 
> struct sigaction sa = { 
>   .sa_flags = SA_RESETHAND,
> };
> 
> However ... on Linux, SA_RESETHAND happens to have the value 0x80000000,
> and therefore, the type of that constant is 'unsigned int'.  And the
> type of sa_flags is 'int'.  So if you compile this test program with
> -Wconversion you get a warning:
> 
> $ gcc -fsyntax-only -Wconversion test.c
> test.c:4:15: warning: signed conversion from ‘unsigned int’ to ‘int’
>    changes value from ‘2147483648’ to ‘-2147483648’ [-Wsign-conversion]
>     4 |  .sa_flags = SA_RESETHAND,
>       |              ^~~~~~~~~~~~
> 
> This strikes me as a (minor) bug in our headers.  Given the ABI constraints
> (this is a flags word passed to the kernel), I think the most straightforward
> fix is probably to change the #define in bits/sigaction.h to
> 
> # define SA_RESETHAND ((int)0x80000000) /* Reset to SIG_DFL on entry to handler.  */
> 
> Anyone got a better idea?

Well, probably not doable now, but is switching to the unsigned counterpart
still possible now?  It would require investigating how this member is
being used out there, to know if we're going to break anyones code, and
integer conversions are very tricky, so it's hard to know, but for a flags
field that is to be used in bitwise operations, I don't expect anyone to
actually use it as an int, but rather as an unsigned that for historic
reasons happens to be signed.

This is also a reminder that new such fields in structures and function
parameters should always be of unsigned types if they're going to hold
flags (or in general, if they're to be treated as something that requires
bitwise operations).

Cheers,
Alex

> 
> zw

-- 
<http://www.alejandro-colomar.es/>
GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Bad interaction between signal constants and -Wsign-conversion
  2023-03-29  0:08 ` Alejandro Colomar
@ 2023-03-30 13:45   ` Zack Weinberg
  2023-03-30 13:59   ` Vincent Lefevre
  1 sibling, 0 replies; 11+ messages in thread
From: Zack Weinberg @ 2023-03-30 13:45 UTC (permalink / raw)
  To: GNU libc development

On Tue, Mar 28, 2023, at 8:08 PM, Alejandro Colomar via Libc-alpha wrote:
> On 3/28/23 03:23, Zack Weinberg via Libc-alpha wrote:
...
>> the type of sa_flags is 'int'
...
> is switching to the unsigned counterpart possible?

Normal usage of struct sigaction wouldn't be affected.  Whether
there are abnormal uses that would ... my feeling is almost
certainly *yes* (and therefore this is not an option), but I have no
idea how to find them.

zw

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Bad interaction between signal constants and -Wsign-conversion
  2023-03-29  0:08 ` Alejandro Colomar
  2023-03-30 13:45   ` Zack Weinberg
@ 2023-03-30 13:59   ` Vincent Lefevre
  2023-03-30 14:09     ` Alejandro Colomar
  1 sibling, 1 reply; 11+ messages in thread
From: Vincent Lefevre @ 2023-03-30 13:59 UTC (permalink / raw)
  To: libc-alpha

On 2023-03-29 02:08:39 +0200, Alejandro Colomar via Libc-alpha wrote:
[about sa_flags in struct sigaction]
> Well, probably not doable now, but is switching to the unsigned counterpart
> still possible now?  It would require investigating how this member is
> being used out there, to know if we're going to break anyones code, and
> integer conversions are very tricky, so it's hard to know, but for a flags
> field that is to be used in bitwise operations, I don't expect anyone to
> actually use it as an int, but rather as an unsigned that for historic
> reasons happens to be signed.
> 
> This is also a reminder that new such fields in structures and function
> parameters should always be of unsigned types if they're going to hold
> flags (or in general, if they're to be treated as something that requires
> bitwise operations).

I entirely agree.

But concerning struct sigaction in particular, shouldn't this be fixed
in POSIX?

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Bad interaction between signal constants and -Wsign-conversion
  2023-03-30 13:59   ` Vincent Lefevre
@ 2023-03-30 14:09     ` Alejandro Colomar
  2023-03-31 15:31       ` Vincent Lefevre
  0 siblings, 1 reply; 11+ messages in thread
From: Alejandro Colomar @ 2023-03-30 14:09 UTC (permalink / raw)
  To: Vincent Lefevre, libc-alpha


[-- Attachment #1.1: Type: text/plain, Size: 1706 bytes --]

Hi Vincent,

On 3/30/23 15:59, Vincent Lefevre wrote:
> On 2023-03-29 02:08:39 +0200, Alejandro Colomar via Libc-alpha wrote:
> [about sa_flags in struct sigaction]
>> Well, probably not doable now, but is switching to the unsigned counterpart
>> still possible now?  It would require investigating how this member is
>> being used out there, to know if we're going to break anyones code, and
>> integer conversions are very tricky, so it's hard to know, but for a flags
>> field that is to be used in bitwise operations, I don't expect anyone to
>> actually use it as an int, but rather as an unsigned that for historic
>> reasons happens to be signed.
>>
>> This is also a reminder that new such fields in structures and function
>> parameters should always be of unsigned types if they're going to hold
>> flags (or in general, if they're to be treated as something that requires
>> bitwise operations).
> 
> I entirely agree.
> 
> But concerning struct sigaction in particular, shouldn't this be fixed
> in POSIX?

IMHO, POSIX, and in general, standards, should follow implementations
rather than lead them.  I think changes should start as vendor
extensions.

For example, timespec::tv_nsec was mandated to be long by POSIX and
C11, but glibc used 'long long' in some cases, because it was
necessary.  I would say using 'unsigned int' here would be a nice GNU
extension, and if it proves its value, POSIX could later pick it.

However, as Zack said, I'm not sure how we could check if any programs
out there are using this member unreasonably.

Cheers,

Alex
-- 
<http://www.alejandro-colomar.es/>
GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Bad interaction between signal constants and -Wsign-conversion
  2023-03-30 14:09     ` Alejandro Colomar
@ 2023-03-31 15:31       ` Vincent Lefevre
  0 siblings, 0 replies; 11+ messages in thread
From: Vincent Lefevre @ 2023-03-31 15:31 UTC (permalink / raw)
  To: libc-alpha

On 2023-03-30 16:09:12 +0200, Alejandro Colomar wrote:
> On 3/30/23 15:59, Vincent Lefevre wrote:
> > But concerning struct sigaction in particular, shouldn't this be fixed
> > in POSIX?
> 
> IMHO, POSIX, and in general, standards, should follow implementations
> rather than lead them.  I think changes should start as vendor
> extensions.

However, there could be a discussion concerning POSIX at the same time.

> For example, timespec::tv_nsec was mandated to be long by POSIX and
> C11, but glibc used 'long long' in some cases, because it was
> necessary.  I would say using 'unsigned int' here would be a nice GNU
> extension, and if it proves its value, POSIX could later pick it.
> 
> However, as Zack said, I'm not sure how we could check if any programs
> out there are using this member unreasonably.

But on the opposite, it is possible that some programs assume that
flags are positive and these programs have not been tested with a
negative flag. So they could already be buggy, and an unsigned int
could fix them.

BTW, some systems seem to have an unsigned sa_flags:

  https://github.com/github/git-msysgit/blob/master/compat/mingw.h
  https://www.google.com/search?q=%22unsigned+long+sa_flags%22
  https://www.google.com/search?q=%22unsigned+int+sa_flags%22

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-03-31 15:31 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-28  1:23 Bad interaction between signal constants and -Wsign-conversion Zack Weinberg
2023-03-28  1:58 ` Paul Eggert
2023-03-28 14:03   ` Cyril Hrubis
2023-03-28 14:53     ` Florian Weimer
2023-03-28 15:04       ` Andreas Schwab
2023-03-28 18:50         ` Florian Weimer
2023-03-29  0:08 ` Alejandro Colomar
2023-03-30 13:45   ` Zack Weinberg
2023-03-30 13:59   ` Vincent Lefevre
2023-03-30 14:09     ` Alejandro Colomar
2023-03-31 15:31       ` Vincent Lefevre

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).