From be6ea829b622e3426ac99e085edbe8b399ce9658 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 24 Jul 2018 17:00:32 +0300 Subject: [PATCH] type: introduce get_promoted_type() One common thing is that we want to parse a binop "a + b" and we want to get the type to promote it to. I've created a function for this. Also if you add an unsigned long to a pointer the result is still a pointer, so in this sense this is a bug fix. Signed-off-by: Dan Carpenter --- smatch.h | 6 ++++++ smatch_sval.c | 6 +----- smatch_type.c | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/smatch.h b/smatch.h index 2061729c..7dbe7fe8 100644 --- a/smatch.h +++ b/smatch.h @@ -375,6 +375,7 @@ int type_bytes(struct symbol *type); int array_bytes(struct symbol *type); struct symbol *get_pointer_type(struct expression *expr); struct symbol *get_type(struct expression *expr); +struct symbol *get_promoted_type(struct symbol *left, struct symbol *right); int type_signed(struct symbol *base_type); int expr_unsigned(struct expression *expr); int expr_signed(struct expression *expr); @@ -1140,6 +1141,11 @@ static inline int type_bits(struct symbol *type) return type->bit_size; } +static inline bool type_is_ptr(struct symbol *type) +{ + return type && (type->type == SYM_PTR || type->type == SYM_ARRAY); +} + static inline int type_unsigned(struct symbol *base_type) { if (!base_type) diff --git a/smatch_sval.c b/smatch_sval.c index d1d74ee2..3aaed7ca 100644 --- a/smatch_sval.c +++ b/smatch_sval.c @@ -428,11 +428,7 @@ sval_t sval_binop(sval_t left, int op, sval_t right) struct symbol *type; sval_t ret; - type = left.type; - if (sval_positive_bits(right) > sval_positive_bits(left)) - type = right.type; - if (type_positive_bits(type) < 31) - type = &int_ctype; + type = get_promoted_type(left.type, right.type); if (type_unsigned(type)) ret = sval_binop_unsigned(type, left, op, right); diff --git a/smatch_type.c b/smatch_type.c index 4265f37e..2c78162f 100644 --- a/smatch_type.c +++ b/smatch_type.c @@ -285,6 +285,23 @@ struct symbol *get_type(struct expression *expr) return ret; } +struct symbol *get_promoted_type(struct symbol *left, struct symbol *right) +{ + struct symbol *ret = &int_ctype; + + if (type_positive_bits(left) > type_positive_bits(ret)) + ret = left; + if (type_positive_bits(right) > type_positive_bits(ret)) + ret = right; + + if (type_is_ptr(left)) + ret = left; + if (type_is_ptr(right)) + ret = right; + + return ret; +} + int type_signed(struct symbol *base_type) { if (!base_type) -- 2.11.4.GIT