From 59b3c105632a6067998ad36631b3eba9b2165219 Mon Sep 17 00:00:00 2001 From: George Koehler Date: Sun, 29 Oct 2017 17:45:10 -0400 Subject: [PATCH] Use (arith) 1 << ... when getting the sign bit. This prevents an overflow reported by @hexcoder- in https://github.com/davidgiven/ack/issues/56 lang/cem/cpp.ansi/LLlex.c used a plain 1 << ... and caused an overflow on machines where sizeof(int) < sizeof(long). Using 1L << ... would work for now but might fail later if arith became long long. C doesn't specify whether negative integers use 2's complement or some other format. Therefore, (arith) 1 << ... has an undefined value. It should still work because the value is some integer where the sign bit is set and all other bits are clear. (unsigned arith) 1 << ... would also get the sign bit, but casting it from unsigned back to signed would make the same undefined value. (arith) -1 << ... would assume 2's complement. --- lang/cem/cpp.ansi/LLlex.c | 2 +- lang/cem/cpp.ansi/arith.h | 4 ++++ lang/cem/cpp.ansi/ch3bin.c | 2 -- lang/m2/comp/cstoper.c | 2 +- lang/m2/comp/type.c | 2 -- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lang/cem/cpp.ansi/LLlex.c b/lang/cem/cpp.ansi/LLlex.c index 7aa0a1eed..5b25a49d4 100644 --- a/lang/cem/cpp.ansi/LLlex.c +++ b/lang/cem/cpp.ansi/LLlex.c @@ -261,7 +261,7 @@ garbage: register int base = 10, vch; register arith val = 0; int ovfl = 0; - arith ubound = ~(1<<(sizeof(arith)*8-1))/(base/2); + arith ubound = max_arith/(base/2); /* Since the preprocessor only knows integers and has * nothing to do with ellipsis we just return when the diff --git a/lang/cem/cpp.ansi/arith.h b/lang/cem/cpp.ansi/arith.h index be74a1887..37a5f63fe 100644 --- a/lang/cem/cpp.ansi/arith.h +++ b/lang/cem/cpp.ansi/arith.h @@ -16,3 +16,7 @@ /* All preprocessor arithmetic should be done in longs. */ #define arith long /* dummy */ + +#define arith_size (sizeof(arith)) +#define arith_sign ((arith) 1 << (arith_size * 8 - 1)) +#define max_arith (~arith_sign) diff --git a/lang/cem/cpp.ansi/ch3bin.c b/lang/cem/cpp.ansi/ch3bin.c index f9f43cfbf..c458487a5 100644 --- a/lang/cem/cpp.ansi/ch3bin.c +++ b/lang/cem/cpp.ansi/ch3bin.c @@ -8,8 +8,6 @@ #include "Lpars.h" #include "arith.h" -#define arith_sign (1L << (sizeof(arith)*8-1)) - ch3bin(pval, pis_uns, oper, val, is_uns) register arith *pval, val; int oper, is_uns, *pis_uns; diff --git a/lang/m2/comp/cstoper.c b/lang/m2/comp/cstoper.c index 9d7fea099..53dfd0e7b 100644 --- a/lang/m2/comp/cstoper.c +++ b/lang/m2/comp/cstoper.c @@ -28,7 +28,7 @@ extern char *symbol2str(); -#define arith_sign ((arith) (1L << (sizeof(arith) * 8 - 1))) +#define arith_sign ((arith) 1 << (sizeof(arith) * 8 - 1)) #ifndef NOCROSS arith full_mask[MAXSIZE+1];/* full_mask[1] == 0xFF, full_mask[2] == 0xFFFF, .. */ diff --git a/lang/m2/comp/type.c b/lang/m2/comp/type.c index bbf4841b4..5912771fe 100644 --- a/lang/m2/comp/type.c +++ b/lang/m2/comp/type.c @@ -51,8 +51,6 @@ arith pointer_size = SZ_POINTER; #endif -#define arith_sign ((arith) (1L << (sizeof(arith) * 8 - 1))) - arith ret_area_size; t_type