aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2016-02-15 17:11:52 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2016-02-15 17:11:52 -0500
commitd2ab9b0ac3e59f6423913669f14a9fe15ab6dc59 (patch)
tree811ce75eec94c9a414ff59a4376d414a563fbcc8
parent2dcaebea079d6e3c2c78bbf3b0948bf5ef707e21 (diff)
downloadpostgresql-d2ab9b0ac3e59f6423913669f14a9fe15ab6dc59.tar.gz
postgresql-d2ab9b0ac3e59f6423913669f14a9fe15ab6dc59.zip
Suppress compiler warnings about useless comparison of unsigned to zero.
Reportedly, some compilers warn about tests like "c < 0" if c is unsigned, and hence complain about the character range checks I added in commit 3bb3f42f3749d40b8d4de65871e8d828b18d4a45. This is a bit of a pain since the regex library doesn't really want to assume that chr is unsigned. However, since any such reconfiguration would involve manual edits of regcustom.h anyway, we can put it on the shoulders of whoever wants to do that to adjust this new range-checking macro correctly. Per gripes from Coverity and Andres.
-rw-r--r--src/backend/regex/regc_lex.c6
-rw-r--r--src/include/regex/regcustom.h11
2 files changed, 14 insertions, 3 deletions
diff --git a/src/backend/regex/regc_lex.c b/src/backend/regex/regc_lex.c
index 00da05571af..d68f88c7fc0 100644
--- a/src/backend/regex/regc_lex.c
+++ b/src/backend/regex/regc_lex.c
@@ -792,13 +792,13 @@ lexescape(struct vars * v)
break;
case CHR('u'):
c = lexdigits(v, 16, 4, 4);
- if (ISERR() || c < CHR_MIN || c > CHR_MAX)
+ if (ISERR() || !CHR_IS_IN_RANGE(c))
FAILW(REG_EESCAPE);
RETV(PLAIN, c);
break;
case CHR('U'):
c = lexdigits(v, 16, 8, 8);
- if (ISERR() || c < CHR_MIN || c > CHR_MAX)
+ if (ISERR() || !CHR_IS_IN_RANGE(c))
FAILW(REG_EESCAPE);
RETV(PLAIN, c);
break;
@@ -816,7 +816,7 @@ lexescape(struct vars * v)
case CHR('x'):
NOTE(REG_UUNPORT);
c = lexdigits(v, 16, 1, 255); /* REs >255 long outside spec */
- if (ISERR() || c < CHR_MIN || c > CHR_MAX)
+ if (ISERR() || !CHR_IS_IN_RANGE(c))
FAILW(REG_EESCAPE);
RETV(PLAIN, c);
break;
diff --git a/src/include/regex/regcustom.h b/src/include/regex/regcustom.h
index 3f1d14e1908..60034daee83 100644
--- a/src/include/regex/regcustom.h
+++ b/src/include/regex/regcustom.h
@@ -68,6 +68,17 @@ typedef int celt; /* type to hold chr, or NOCELT */
#define CHR_MAX 0x7ffffffe /* CHR_MAX-CHR_MIN+1 must fit in an int, and
* CHR_MAX+1 must fit in both chr and celt */
+/*
+ * Check if a chr value is in range. Ideally we'd just write this as
+ * ((c) >= CHR_MIN && (c) <= CHR_MAX)
+ * However, if chr is unsigned and CHR_MIN is zero, the first part of that
+ * is a no-op, and certain overly-nannyish compilers give warnings about it.
+ * So we leave that out here. If you want to make chr signed and/or CHR_MIN
+ * not zero, redefine this macro as above. Callers should assume that the
+ * macro may multiply evaluate its argument, even though it does not today.
+ */
+#define CHR_IS_IN_RANGE(c) ((c) <= CHR_MAX)
+
/* functions operating on chr */
#define iscalnum(x) pg_wc_isalnum(x)
#define iscalpha(x) pg_wc_isalpha(x)