https://bugs.llvm.org/show_bug.cgi?id=46025
Bug ID: 46025
Summary: The implicit-integer-sign-change is pointless for
symbolic constants
Product: clang
Version: 10.0
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: C
Assignee: unassignedclangb...@nondot.org
Reporter: br...@clisp.org
CC: blitzrak...@gmail.com, dgre...@apple.com,
erik.pilking...@gmail.com, llvm-bugs@lists.llvm.org,
richard-l...@metafoo.co.uk
Created attachment 23512
--> https://bugs.llvm.org/attachment.cgi?id=23512&action=edit
Test case
The -fsanitize=implicit-integer-sign-change checks can be useful in general.
But when involving symbolic constants defined by a library's header file, as I
user I don't control whether they evaluate to 'int' or 'unsigned int'.
Here's a test case:
============================ foo.c ============================
#include <signal.h>
int
main ()
{
struct sigaction act;
act.sa_flags = /* SA_NODEFER | SA_ONSTACK | */ SA_RESETHAND;
return 0;
}
===============================================================
$ clang -Wall foo.c -E | grep sa_flags
int sa_flags;
act.sa_flags = 0x80000000;
$ clang -Wall foo.c -fsanitize=implicit-integer-sign-change
$ ./a.out
foo.c:7:50: runtime error: implicit conversion from type 'unsigned int' of
value 2147483648 (32-bit, unsigned) to type 'int' changed the value to
-2147483648 (32-bit, signed)
So, glibc defines the 'sa_flags' field as being of type 'int' (like POSIX
mandates, see
https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html).
glibc also defines SA_RESETHAND as 0x80000000. Per ISO C, this constant is of
type 'unsigned int'. The sanitizer then complains about an implicit conversion
from 'unsigned int' to 'int'.
This is not useful, as the programmer did not make a mistake here.
As a programmer, I do not want to add an explicit cast:
act.sa_flags = (int)(/* SA_NODEFER | SA_ONSTACK | */ SA_RESETHAND);
because generally, such explicit casts introduce bugs when the standards change
or some platform is not 100% standards compliant.
The library authors also surely don't want to write
#define SA_RESETHAND (~0x7fffffff)
because 1) the value is meant to be a single bit, and writing it this way would
obfuscate this bit (mask) aspect, 2) there are hundreds of such bit masks
defined in the libc headers (think of all possible ioctl values).
The library authors also surely don't want to write
#define SA_RESETHAND (int)0x80000000
either, because then SA_RESETHAND would not be usable in a preprocessor
expression (e.g., squid/src/tools.cc has "#if SA_RESETHAND == 0 &&
!_SQUID_WINDOWS_").
So, if clang does not change the implicit-integer-sign-change sanitizer, I can
only recommend to everyone to not use this particular sanitizer.
--
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs