m4-commit
[Top][All Lists]
Advanced

[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;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]