This checking is currently done by check_assignment_types() but this is not adequate, for example because it allows a void pointer while a pointer of the specific type is needed. So, add a custom checking function. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- verify-format.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/verify-format.c b/verify-format.c index 90fe0ede0431..1b40b2c796a2 100644 --- a/verify-format.c +++ b/verify-format.c @@ -146,6 +146,41 @@ static int printf_fmt_string(struct format_type *fmt, return !(*typediff = check_printf_string(fmt, ctype)); } + +#define MOD_IGN (MOD_QUALIFIER | MOD_FUN_ATTR) +static inline const char *compare_pointer(struct symbol *target, struct symbol *source) +{ + unsigned long modt = target->ctype.modifiers & MOD_IGN & ~MOD_REV_QUAL; + unsigned long mods = source->ctype.modifiers & MOD_IGN & MOD_REV_QUAL; + + return type_difference(&target->ctype, &source->ctype, mods, modt); +} + +// For 'n' specifier +static const char *check_printf_length(struct format_type *fmt, struct symbol *source) +{ + const char *typediff = "different base types"; + struct symbol *target = fmt->type; + + examine_pointer_target(target); + examine_pointer_target(source); + + if (type_class(source, &source) != CLASS_PTR) + return typediff; + if (source->ctype.as) + return "different address spaces"; + + return compare_pointer(target, source); +} + +static int printf_fmt_length(struct format_type *fmt, + struct expression **expr, + struct symbol *ctype, + const char **typediff) +{ + return !(*typediff = check_printf_length(fmt, ctype)); +} + static int printf_fmt_pointer(struct format_type *fmt, struct expression **expr, struct symbol *ctype, @@ -335,7 +370,7 @@ static struct format_type *parse_printf_get_fmt(struct format_type *type, /* pointer to an de-referenced int/etc */ // todo - we should construct pointer to int/etc // // also should not have any flags or widths for this - type->test = printf_fmt_pointer; + type->test = printf_fmt_length; type->type = &const_ptr_ctype; break; default: -- 2.28.0