Bug 17898 - Incorrect usage of isdigit, etc.
Summary: Incorrect usage of isdigit, etc.
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: other (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-10-08 20:36 UTC by M Welinder
Modified: 2021-11-11 16:11 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-10-02 20:59:35


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description M Welinder 2004-10-08 20:36:33 UTC
Doing a
> find . -name \*.c | xargs -n99 egrep -w
'is(upper|alnum|alpha|lower|print|space|digit)' /dev/null

on the gcc 3.4.0 source shows lots of places where the isdigit and friends
are called on plain, possibly signed, characters.  These need to be fixed
to cast the argument to "unsigned char".  (Lots of instances already do
that.)

Note: several places have casts to int.  That will silence gcc on solaris,
for example, but the code will still be wrong.

These all appear wrong:

./libobjc/gc.c:  while (isdigit (*++type))
./gcc/config/frv/frv.c:  if (code != 0 && !isalpha (code))
./gcc/ada/adaint.c:      || (strlen (name) > 1 && isalpha (name[0]) && name[1]
== ':')
./boehm-gc/os_dep.c:    while (isspace(c)) c = stat_buf[buf_offset++];
./boehm-gc/os_dep.c:    while (!isspace(c)) c = stat_buf[buf_offset++];
./boehm-gc/os_dep.c:    while (isspace(c)) c = stat_buf[buf_offset++];
./boehm-gc/os_dep.c:    while (isdigit(c)) {
./boehm-gc/cord/de.c:    } else if (c < 0x100 && isdigit(c)){
./boehm-gc/cord/de_win.c:       while (isspace(*command_line)) command_line++;
./boehm-gc/cord/de_win.c:       while (*command_line != 0 &&
!isspace(*command_line)) command_line++;
./boehm-gc/cord/de_win.c:       while (isspace(*command_line)) command_line++;
./boehm-gc/cord/de_win.c:        while (*p != 0 && !isspace(*p)) p++;



This is wrong, but being a test case might not need fixing:

./gcc/testsuite/gcc.c-torture/execute/991112-1.c:  return isprint (c) ? 1 : 2;

These look like someone got a warning and then did the wrong thing to resolve
it.  The cast should be to unsigned char, not int:

./libjava/libltdl/ltdl.c:      if (!isspace ((int) *p))
./libjava/libltdl/ltdl.c:         while (*end && !isspace((int) *end))
./libjava/libltdl/ltdl.c:      if (isspace ((int) *p))
./libjava/libltdl/ltdl.c:         while (*end && !isspace ((int) *end))
./libjava/libltdl/ltdl.c:           if (isalnum ((int)(base_name[i])))

Wrong as above:
./gcc/ada/adadecode.c:#define ISDIGIT(c) isdigit(c)
and later
      while (ISDIGIT ((int) ada_name[(int) len - 1 - n_digits]))
Comment 1 Andrew Pinski 2004-10-08 20:48:50 UTC
./libobjc/gc.c:  while (isdigit (*++type))
is not wrong because we cannot get greater than 127 in type at all (this is an encoding which does not 
use non ascii characters).

And these cannot recieve characters greater than 127 either (unless something is wrong with your 
machine):
./boehm-gc/os_dep.c:    while (isspace(c)) c = stat_buf[buf_offset++];
./boehm-gc/os_dep.c:    while (!isspace(c)) c = stat_buf[buf_offset++];
./boehm-gc/os_dep.c:    while (isspace(c)) c = stat_buf[buf_offset++];
./boehm-gc/os_dep.c:    while (isdigit(c)) {

Also :
./boehm-gc/cord/de.c:    } else if (c < 0x100 && isdigit(c)){
is right.

Also it is 4.4 BSD extension to accept greater than the 0xFF.

And most of these come from up stream projects.
libltdl/ltdl.c belongs to libtool, report it to them.

Comment 2 Andrew Pinski 2004-10-08 20:50:23 UTC
Also:
./gcc/config/frv/frv.c:  if (code != 0 && !isalpha (code))
is right, code will always be less than 127 unless someone messed up the compiler or inline asm so we 
don't need to change that one.
Comment 3 Andrew Pinski 2004-10-08 20:53:23 UTC
./gcc/ada/adadecode.c:#define ISDIGIT(c) isdigit(c)
and later
      while (ISDIGIT ((int) ada_name[(int) len - 1 - n_digits]))

Will always be right so it does not matter either.

And the testcase does not matter either because we pass only below 127.

So the remaining are from upstream projects, report it to them.

Confirming and ...
Comment 4 Andrew Pinski 2004-10-08 20:53:53 UTC
Suspending as the bug is in upstream projects.
Comment 5 M Welinder 2004-10-08 21:03:00 UTC
Well, that still leaves the adaint.c problem where the character is coming
from a filename.

Any reason not to fix the cast in adadecode.c to be to "unsigned int"?
The only function of the cast is to shut up gcc, so we might as well cast to
the right type.
Comment 6 John David Anglin 2020-03-15 13:43:37 UTC
The usage of ISDIGIT in adadecode.c now causes a warning and build failure:

/test/gnu/gcc/objdir/./prev-gcc/xg++ -B/test/gnu/gcc/objdir/./prev-gcc/ -B/opt/g
nu/gcc/gcc-10/hppa2.0w-hp-hpux11.11/bin/ -nostdinc++ -B/test/gnu/gcc/objdir/prev
-hppa2.0w-hp-hpux11.11/libstdc++-v3/src/.libs -B/test/gnu/gcc/objdir/prev-hppa2.
0w-hp-hpux11.11/libstdc++-v3/libsupc++/.libs  -I/test/gnu/gcc/objdir/prev-hppa2.
0w-hp-hpux11.11/libstdc++-v3/include/hppa2.0w-hp-hpux11.11  -I/test/gnu/gcc/objd
ir/prev-hppa2.0w-hp-hpux11.11/libstdc++-v3/include  -I/test/gnu/gcc/gcc/libstdc+
+-v3/libsupc++ -L/test/gnu/gcc/objdir/prev-hppa2.0w-hp-hpux11.11/libstdc++-v3/sr
c/.libs -L/test/gnu/gcc/objdir/prev-hppa2.0w-hp-hpux11.11/libstdc++-v3/libsupc++
/.libs -fno-PIE -c  -DIN_GCC_FRONTEND -g -O2 -fno-checking -DIN_GCC     -fno-exc
eptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-s
trings -Wcast-qual -Wno-error=format-diag -mdisable-indexing -Wmissing-format-at
tribute -Woverloaded-virtual -Wno-long-long -Wno-variadic-macros -Wno-overlength
-strings -Werror -fno-common  -DHAVE_CONFIG_H -I. -Iada -I../../gcc/gcc -I../../
gcc/gcc/ada -I../../gcc/gcc/../include -I../../gcc/gcc/../libcpp/include -I/opt/gnu/gcc/gmp/include  -I../../gcc/gcc/../libdecnumber -I../../gcc/gcc/../libdecnumber/dpd -I../libdecnumber -I../../gcc/gcc/../libbacktrace   -o ada/adadecode.o -MT ada/adadecode.o -MMD -MP -MF ada/.deps/adadecode.TPo ../../gcc/gcc/ada/adadecode.c
In file included from ../../gcc/gcc/ada/adadecode.c:35:
../../gcc/gcc/ada/adadecode.c: In function 'void __gnat_decode(const char*, char*, int)':
../../gcc/gcc/ada/adadecode.c:260:34: error: array subscript has type 'char' [-Werror=char-subscripts]
  260 |     while (ISDIGIT (ada_name[last]) && last > 0)
      |                     ~~~~~~~~~~~~~^
../../gcc/gcc/ada/adadecode.c:260:12: note: in expansion of macro 'ISDIGIT'
  260 |     while (ISDIGIT (ada_name[last]) && last > 0)
      |            ^~~~~~~
cc1plus: all warnings being treated as errors
make[3]: *** [Makefile:1117: ada/adadecode.o] Error 1
Comment 7 Eric Gallager 2021-11-11 16:11:57 UTC
bug 95177 is similar