This checking is currently done by check_assignment_types() but this is not adequate, for example because it allows a void pointer for the string argument while a warning should be issued. So, add a custom checking function. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- verify-format.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/verify-format.c b/verify-format.c index 0ef2cb863ae9..90fe0ede0431 100644 --- a/verify-format.c +++ b/verify-format.c @@ -106,12 +106,44 @@ static int printf_fmt_numtype(struct format_type *fmt, return check_assignment_types(fmt->type, expr, typediff); } +// For 's' & 'S' specifiers +static const char *check_printf_string(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"; + + // get the base type + type_class(source->ctype.base_type, &source); + type_class(source, &source); + + if (target == &const_string_ctype) { + if (source == &char_ctype) + return NULL; + if (source == &uchar_ctype) + return NULL; + if (source == &schar_ctype) + return NULL; + } if (target == &const_wstring_ctype) { + if (source == wchar_ctype) + return NULL; + } + return typediff; +} + static int printf_fmt_string(struct format_type *fmt, struct expression **expr, struct symbol *ctype, const char **typediff) { - return check_assignment_types(fmt->type, expr, typediff); + return !(*typediff = check_printf_string(fmt, ctype)); } static int printf_fmt_pointer(struct format_type *fmt, -- 2.28.0