Skip to content

Commit

Permalink
Use (arith) 1 << ... when getting the sign bit.
Browse files Browse the repository at this point in the history
This prevents an overflow reported by @hexcoder- in
#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.
  • Loading branch information
kernigh committed Oct 29, 2017
1 parent d36807b commit 59b3c10
Show file tree
Hide file tree
Showing 5 changed files with 6 additions and 6 deletions.
2 changes: 1 addition & 1 deletion lang/cem/cpp.ansi/LLlex.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ GetToken(ptok)
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
Expand Down
4 changes: 4 additions & 0 deletions lang/cem/cpp.ansi/arith.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
2 changes: 0 additions & 2 deletions lang/cem/cpp.ansi/ch3bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion lang/m2/comp/cstoper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, .. */
Expand Down
2 changes: 0 additions & 2 deletions lang/m2/comp/type.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 59b3c10

Please sign in to comment.