[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Changes to m4/src/Attic/eval.c,v [branch-1_4]
From: |
Eric Blake |
Subject: |
Changes to m4/src/Attic/eval.c,v [branch-1_4] |
Date: |
Tue, 27 Jun 2006 13:31:48 +0000 |
CVSROOT: /sources/m4
Module name: m4
Branch: branch-1_4
Changes by: Eric Blake <ericb> 06/06/27 13:31:44
Index: src/eval.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/eval.c,v
retrieving revision 1.1.1.1.2.3
retrieving revision 1.1.1.1.2.4
diff -u -b -r1.1.1.1.2.3 -r1.1.1.1.2.4
--- src/eval.c 23 Jun 2006 13:06:10 -0000 1.1.1.1.2.3
+++ src/eval.c 27 Jun 2006 13:31:44 -0000 1.1.1.1.2.4
@@ -22,7 +22,8 @@
/* This file contains the functions to evaluate integer expressions for
the "eval" macro. It is a little, fairly self-contained module, with
its own scanner, and a recursive descent parser. The only entry point
- is evaluate (). */
+ is evaluate (). For POSIX semantics of the "eval" macro, the type
+ eval_t must be a 32-bit signed integer. */
#include "m4.h"
@@ -579,14 +580,20 @@
if ((er = add_term (et, &v2)) != NO_ERROR)
return er;
+ /* Shifting by a negative number, or by greater than the width, is
+ undefined in C, but POSIX requires eval to operate on 32-bit signed
+ numbers. Explicitly mask the right argument to ensure defined
+ behavior. */
switch (op)
{
case LSHIFT:
- *v1 = *v1 << v2;
+ *v1 = *v1 << (v2 & 0x1f);
break;
case RSHIFT:
- *v1 = *v1 >> v2;
+ /* This assumes 2's-complement with sign-extension, since shifting
+ a negative number right is implementation-defined in C. */
+ *v1 = *v1 >> (v2 & 0x1f);
break;
default:
@@ -661,6 +668,9 @@
case DIVIDE:
if (v2 == 0)
return DIVIDE_ZERO;
+ else if (v2 == -1)
+ /* Avoid the x86 SIGFPE on INT_MIN / -1. */
+ *v1 = -*v1;
else
*v1 = *v1 / v2;
break;
@@ -668,6 +678,9 @@
case MODULO:
if (v2 == 0)
return MODULO_ZERO;
+ else if (v2 == -1)
+ /* Avoid the x86 SIGFPE on INT_MIN % -1. */
+ *v1 = 0;
else
*v1 = *v1 % v2;
break;