diff options
author | François-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2021-12-16 18:38:30 +0100 |
---|---|---|
committer | François-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2021-12-18 09:21:16 +0100 |
commit | 21423a1dfa079d4cd218f69d2fab9fe65a69fedb (patch) | |
tree | 08f1191472543839ad785d3bc99b304118528fba /libgfortran/libgfortran.h | |
parent | f18cbc1ee1f421a0dd79dc389bef9a23dd4a761d (diff) | |
download | gcc-21423a1dfa079d4cd218f69d2fab9fe65a69fedb.zip gcc-21423a1dfa079d4cd218f69d2fab9fe65a69fedb.tar.gz gcc-21423a1dfa079d4cd218f69d2fab9fe65a69fedb.tar.bz2 |
Fortran: Cast arguments of <ctype.h> functions to unsigned char
Functions from <ctype.h> should only be called on values that can be
represented by unsigned char. On targets where char is a signed type,
some of libgfortran calls have undefined behaviour.
The solution is to cast the argument to unsigned char type. I’ve defined
macros in libgfortran.h to do so, to retain legibility of the library
code.
PR libfortran/95177
libgfortran/ChangeLog
* libgfortran.h: include ctype.h, provide safe macros.
* io/format.c: use safe macros.
* io/list_read.c: use safe macros.
* io/read.c: use safe macros.
* io/write.c: use safe macros.
* runtime/environ.c: use safe macros.
Diffstat (limited to 'libgfortran/libgfortran.h')
-rw-r--r-- | libgfortran/libgfortran.h | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h index 285c36a..93e3591 100644 --- a/libgfortran/libgfortran.h +++ b/libgfortran/libgfortran.h @@ -39,6 +39,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* config.h MUST be first because it can affect system headers. */ #include "config.h" +#include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <stddef.h> @@ -103,6 +104,20 @@ typedef off_t gfc_offset; #endif +/* These functions from <ctype.h> should only be used on values that can be + represented as unsigned char, otherwise the behavior is undefined. + Some targets have a char type that is signed, so we cast the argument + to unsigned char. See: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95177 + https://wiki.sei.cmu.edu/confluence/x/BNcxBQ + */ + +#define safe_isalnum(x) isalnum((unsigned char) (x)) +#define safe_isdigit(x) isdigit((unsigned char) (x)) +#define safe_tolower(x) tolower((unsigned char) (x)) +#define safe_toupper(x) toupper((unsigned char) (x)) + + /* The following macros can be used to annotate conditions which are likely or unlikely to be true. Avoid using them when a condition is only slightly more likely/less unlikely than average to avoid the performance penalties of |