Added helper functions for PLUS, MINUS and TIMES to help constrain the result types and prevent surprising integer promotions

This commit is contained in:
Neil Brown 2008-02-29 00:20:52 +00:00
parent 2ca965ebf0
commit 24dc839cfb
2 changed files with 29 additions and 4 deletions

View File

@ -842,9 +842,9 @@ cgenDyadic m A.Subtr e f = call genFuncDyadic m "subtr" e f
cgenDyadic m A.Mul e f = call genFuncDyadic m "mul" e f
cgenDyadic m A.Div e f = call genFuncDyadic m "div" e f
cgenDyadic m A.Rem e f = call genFuncDyadic m "rem" e f
cgenDyadic _ A.Plus e f = call genSimpleDyadic "+" e f
cgenDyadic _ A.Minus e f = call genSimpleDyadic "-" e f
cgenDyadic _ A.Times e f = call genSimpleDyadic "*" e f
cgenDyadic m A.Plus e f = call genFuncDyadic m "plus" e f
cgenDyadic m A.Minus e f = call genFuncDyadic m "minus" e f
cgenDyadic m A.Times e f = call genFuncDyadic m "times" e f
cgenDyadic m A.LeftShift e f = call genFuncDyadic m "lshift" e f
cgenDyadic m A.RightShift e f = call genFuncDyadic m "rshift" e f
cgenDyadic _ A.BitAnd e f = call genSimpleDyadic "&" e f

View File

@ -202,6 +202,25 @@ static inline int occam_check_retype (int src, int dest, const char *pos) {
} \
}
// The main purpose of these three - since they don't need to check for overflow -
// is to constrain the types of the results to prevent unexpected integer promotions
#define MAKE_PLUS(type) \
static inline type occam_plus_##type (type, type, const char *) occam_unused; \
static inline type occam_plus_##type (type a, type b, const char *pos) { \
return a + b; \
}
#define MAKE_MINUS(type) \
static inline type occam_minus_##type (type, type, const char *) occam_unused; \
static inline type occam_minus_##type (type a, type b, const char *pos) { \
return a - b; \
}
#define MAKE_TIMES(type) \
static inline type occam_times_##type (type, type, const char *) occam_unused; \
static inline type occam_times_##type (type a, type b, const char *pos) { \
return a * b; \
}
#define MAKE_ALL_SIGNED(type,flag) \
MAKE_RANGE_CHECK(type,flag) \
MAKE_ADD(type) \
@ -210,7 +229,10 @@ static inline int occam_check_retype (int src, int dest, const char *pos) {
MAKE_DIV(type) \
MAKE_REM(type) \
MAKE_NEGATE(type) \
MAKE_SHIFT(u##type, type)
MAKE_SHIFT(u##type, type) \
MAKE_PLUS(type) \
MAKE_MINUS(type) \
MAKE_TIMES(type)
//{{{ uint8_t
MAKE_RANGE_CHECK(uint8_t, "%d")
@ -219,6 +241,9 @@ MAKE_SUBTR(uint8_t)
MAKE_MUL(uint8_t)
MAKE_DIV(uint8_t)
MAKE_SHIFT(uint8_t,uint8_t)
MAKE_PLUS(uint8_t)
MAKE_MINUS(uint8_t)
MAKE_TIMES(uint8_t)
// occam's only unsigned type, so we can use % directly.
static inline uint8_t occam_rem_uint8_t (uint8_t, uint8_t, const char *) occam_unused;