1.1 --- a/templates/native.c Sat Dec 03 16:26:03 2016 +0100
1.2 +++ b/templates/native.c Sat Dec 03 16:44:55 2016 +0100
1.3 @@ -1,8 +1,10 @@
1.4 #include <stdlib.h> /* abs, exit */
1.5 #include <unistd.h> /* read, write */
1.6 +#include <limits.h> /* INT_MAX, INT_MIN */
1.7 #include <math.h> /* ceil, log10, pow */
1.8 #include <string.h> /* strcmp, strncpy, strlen */
1.9 #include <stdio.h> /* snprintf */
1.10 +#include <errno.h> /* errno */
1.11 #include "types.h"
1.12 #include "exceptions.h"
1.13 #include "ops.h"
1.14 @@ -109,8 +111,13 @@
1.15 int i = _data->intvalue;
1.16 int j = other->intvalue;
1.17
1.18 + /* Test for overflow. */
1.19 + if (((i > 0) && (j > 0) && (i > INT_MAX - j)) ||
1.20 + ((i < 0) && (j < 0) && (i < INT_MIN - j)))
1.21 +
1.22 + __raise_overflow_error();
1.23 +
1.24 /* Return the new integer. */
1.25 - /* NOTE: No overflow test applied. */
1.26 return __new_int(i + j);
1.27 }
1.28
1.29 @@ -122,8 +129,13 @@
1.30 int i = _data->intvalue;
1.31 int j = other->intvalue;
1.32
1.33 + /* Test for overflow. */
1.34 + if (((i < 0) && (j > 0) && (i < INT_MIN + j)) ||
1.35 + ((i > 0) && (j < 0) && (i > INT_MAX + j)))
1.36 +
1.37 + __raise_overflow_error();
1.38 +
1.39 /* Return the new integer. */
1.40 - /* NOTE: No overflow test applied. */
1.41 return __new_int(i - j);
1.42 }
1.43
1.44 @@ -135,8 +147,15 @@
1.45 int i = _data->intvalue;
1.46 int j = other->intvalue;
1.47
1.48 + /* Test for overflow. */
1.49 + if (((i > 0) && (j > 0) && (i > INT_MAX / j)) ||
1.50 + ((i < 0) && (j < 0) && (i > INT_MAX / j)) ||
1.51 + ((i < 0) && (j > 0) && (i < INT_MIN / j)) ||
1.52 + ((i > 0) && (j < 0) && (j < INT_MIN / i)))
1.53 +
1.54 + __raise_overflow_error();
1.55 +
1.56 /* Return the new integer. */
1.57 - /* NOTE: No overflow test applied. */
1.58 return __new_int(i * j);
1.59 }
1.60
1.61 @@ -148,8 +167,13 @@
1.62 int i = _data->intvalue;
1.63 int j = other->intvalue;
1.64
1.65 + /* Test for division by zero or overflow. */
1.66 + if (j == 0)
1.67 + __raise_zero_division_error();
1.68 + else if ((j == -1) && (i == INT_MIN))
1.69 + __raise_overflow_error();
1.70 +
1.71 /* Return the new integer. */
1.72 - /* NOTE: No overflow test applied. */
1.73 return __new_int(i / j);
1.74 }
1.75
1.76 @@ -161,8 +185,13 @@
1.77 int i = _data->intvalue;
1.78 int j = other->intvalue;
1.79
1.80 + /* Test for division by zero or overflow. */
1.81 + if (j == 0)
1.82 + __raise_zero_division_error();
1.83 + else if ((j == -1) && (i == INT_MIN))
1.84 + __raise_overflow_error();
1.85 +
1.86 /* Return the new integer. */
1.87 - /* NOTE: No overflow test applied. */
1.88 return __new_int(i % j);
1.89 }
1.90
1.91 @@ -172,6 +201,10 @@
1.92 /* _data interpreted as int */
1.93 int i = _data->intvalue;
1.94
1.95 + /* Test for overflow. */
1.96 + if (i == INT_MIN)
1.97 + __raise_overflow_error();
1.98 +
1.99 /* Return the new integer. */
1.100 return __new_int(-i);
1.101 }
1.102 @@ -183,10 +216,18 @@
1.103 /* _data and other interpreted as int */
1.104 int i = _data->intvalue;
1.105 int j = other->intvalue;
1.106 + int k;
1.107 +
1.108 + errno = 0;
1.109 + k = (int) pow(i, j);
1.110 +
1.111 + /* Test for overflow. */
1.112 +
1.113 + if (errno == ERANGE)
1.114 + __raise_overflow_error();
1.115
1.116 /* Return the new integer. */
1.117 - /* NOTE: No overflow test applied. */
1.118 - return __new_int((int) pow(i, j));
1.119 + return __new_int(k);
1.120 }
1.121
1.122 __attr __fn_native__int_and(__attr __args[])