summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <meyering@fb.com>2013-11-18 17:53:33 -0800
committerJim Meyering <meyering@fb.com>2013-11-21 20:57:58 -0800
commitf8d6a5d3b5ea5d098f2973c66041613b68812ad2 (patch)
treea142db27819dd85d873d7c04d134c41a448caa73 /src
parent9a9b4c59babc60e15a79cf7db8167d42e68e44b9 (diff)
downloadgrep-f8d6a5d3b5ea5d098f2973c66041613b68812ad2.tar.gz
dfa: avoid undefined behavior of "1 << 31"
* src/dfa.c (charclass): Change type from "int" to "unsigned int". (tstbit): Rather than shifting "1" left to form a mask, shift the LHS bits the right and use "1" as the mask. Also, return bool, rather than "int". (setbit, clrbit, dfastate): Don't shift "1" (aka (int)1) left by 31 bits. Instead, use "1U" as the operand, to avoid undefined behavior. Spotted by gcc's new -fsanitize=undefined. Co-authored-by: Paul Eggert <eggert@cs.ucla.edu>
Diffstat (limited to 'src')
-rw-r--r--src/dfa.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/src/dfa.c b/src/dfa.c
index 92c410e2..f196b8a1 100644
--- a/src/dfa.c
+++ b/src/dfa.c
@@ -88,7 +88,7 @@
#define CHARCLASS_INTS ((NOTCHAR + INTBITS - 1) / INTBITS)
/* Sets of unsigned characters are stored as bit vectors in arrays of ints. */
-typedef int charclass[CHARCLASS_INTS];
+typedef unsigned int charclass[CHARCLASS_INTS];
/* Convert a possibly-signed character to an unsigned character. This is
a bit safer than casting to unsigned char, since it catches some type
@@ -547,22 +547,22 @@ prtok (token t)
/* Stuff pertaining to charclasses. */
-static int
+static bool
tstbit (unsigned int b, charclass const c)
{
- return c[b / INTBITS] & 1 << b % INTBITS;
+ return c[b / INTBITS] >> b % INTBITS & 1;
}
static void
setbit (unsigned int b, charclass c)
{
- c[b / INTBITS] |= 1 << b % INTBITS;
+ c[b / INTBITS] |= 1U << b % INTBITS;
}
static void
clrbit (unsigned int b, charclass c)
{
- c[b / INTBITS] &= ~(1 << b % INTBITS);
+ c[b / INTBITS] &= ~(1U << b % INTBITS);
}
static void
@@ -2738,7 +2738,7 @@ dfastate (state_num s, struct dfa *d, state_num trans[])
/* Set the transitions for each character in the current label. */
for (j = 0; j < CHARCLASS_INTS; ++j)
for (k = 0; k < INTBITS; ++k)
- if (labels[i][j] & 1 << k)
+ if (labels[i][j] & 1U << k)
{
int c = j * INTBITS + k;