From patchwork Mon Oct 29 15:39:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Dooks X-Patchwork-Id: 10659441 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CC6943E9D for ; Mon, 29 Oct 2018 15:39:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CC8B529AC7 for ; Mon, 29 Oct 2018 15:39:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C16B329AD3; Mon, 29 Oct 2018 15:39:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8CEFC29AC7 for ; Mon, 29 Oct 2018 15:39:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727085AbeJ3A3D (ORCPT ); Mon, 29 Oct 2018 20:29:03 -0400 Received: from imap1.codethink.co.uk ([176.9.8.82]:59229 "EHLO imap1.codethink.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727521AbeJ3A3D (ORCPT ); Mon, 29 Oct 2018 20:29:03 -0400 Received: from [148.252.241.226] (helo=rainbowdash) by imap1.codethink.co.uk with esmtpsa (Exim 4.84_2 #1 (Debian)) id 1gH9dx-0005vN-T1; Mon, 29 Oct 2018 15:39:53 +0000 Received: from ben by rainbowdash with local (Exim 4.91) (envelope-from ) id 1gH9dx-0003eS-Iz; Mon, 29 Oct 2018 15:39:53 +0000 From: Ben Dooks To: linux-sparse@vger.kernel.org Cc: Ben Dooks Subject: [PATCH 1/5] tokenize: check show_string() for NULL pointer Date: Mon, 29 Oct 2018 15:39:48 +0000 Message-Id: <20181029153952.13927-2-ben.dooks@codethink.co.uk> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181029153952.13927-1-ben.dooks@codethink.co.uk> References: <20181029153952.13927-1-ben.dooks@codethink.co.uk> MIME-Version: 1.0 Sender: linux-sparse-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sparse@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Fix issue where show_string() being passed a NULL pointer by accident. This only happened during debugging, but would be a useful addition to the checks in this function. Signed-off-by: Ben Dooks --- tokenize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokenize.c b/tokenize.c index 99b9580..c32f8c7 100644 --- a/tokenize.c +++ b/tokenize.c @@ -124,7 +124,7 @@ const char *show_string(const struct string *string) char *ptr; int i; - if (!string->length) + if (!string || !string->length) return ""; ptr = buffer; *ptr++ = '"'; From patchwork Mon Oct 29 15:39:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Dooks X-Patchwork-Id: 10659443 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E1A5D14BD for ; Mon, 29 Oct 2018 15:39:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DEFA229AC7 for ; Mon, 29 Oct 2018 15:39:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D3BB129AD7; Mon, 29 Oct 2018 15:39:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F053829AD1 for ; Mon, 29 Oct 2018 15:39:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727520AbeJ3A3E (ORCPT ); Mon, 29 Oct 2018 20:29:04 -0400 Received: from imap1.codethink.co.uk ([176.9.8.82]:59234 "EHLO imap1.codethink.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727503AbeJ3A3D (ORCPT ); Mon, 29 Oct 2018 20:29:03 -0400 Received: from [148.252.241.226] (helo=rainbowdash) by imap1.codethink.co.uk with esmtpsa (Exim 4.84_2 #1 (Debian)) id 1gH9dx-0005vO-To; Mon, 29 Oct 2018 15:39:54 +0000 Received: from ben by rainbowdash with local (Exim 4.91) (envelope-from ) id 1gH9dx-0003eV-KL; Mon, 29 Oct 2018 15:39:53 +0000 From: Ben Dooks To: linux-sparse@vger.kernel.org Cc: Ben Dooks Subject: [PATCH 2/5] add ptr_ctype_noderef for use with prinft code Date: Mon, 29 Oct 2018 15:39:49 +0000 Message-Id: <20181029153952.13927-3-ben.dooks@codethink.co.uk> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181029153952.13927-1-ben.dooks@codethink.co.uk> References: <20181029153952.13927-1-ben.dooks@codethink.co.uk> MIME-Version: 1.0 Sender: linux-sparse-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sparse@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a specific type for a pointer that shouldn't be dereferenced. This is used by the printf format parser for the %p case. Signed-off-by: Ben Dooks --- symbol.c | 4 +++- symbol.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/symbol.c b/symbol.c index 26906ec..b1e7db1 100644 --- a/symbol.c +++ b/symbol.c @@ -674,7 +674,8 @@ struct symbol bool_ctype, void_ctype, type_ctype, llong_ctype, sllong_ctype, ullong_ctype, lllong_ctype, slllong_ctype, ulllong_ctype, float_ctype, double_ctype, ldouble_ctype, - string_ctype, ptr_ctype, lazy_ptr_ctype, + string_ctype, + ptr_ctype, ptr_ctype_noderef, lazy_ptr_ctype, incomplete_ctype, label_ctype, bad_ctype, null_ctype; @@ -740,6 +741,7 @@ static const struct ctype_declare { { &string_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &char_ctype }, { &ptr_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &void_ctype }, + { &ptr_ctype_noderef, SYM_PTR, MOD_NODEREF, &bits_in_pointer, &pointer_alignment, &void_ctype }, { &null_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &void_ctype }, { &label_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &void_ctype }, { &lazy_ptr_ctype, SYM_PTR, 0, &bits_in_pointer, &pointer_alignment, &void_ctype }, diff --git a/symbol.h b/symbol.h index 3274496..1f338f5 100644 --- a/symbol.h +++ b/symbol.h @@ -266,7 +266,7 @@ extern struct symbol bool_ctype, void_ctype, type_ctype, llong_ctype, sllong_ctype, ullong_ctype, lllong_ctype, slllong_ctype, ulllong_ctype, float_ctype, double_ctype, ldouble_ctype, - string_ctype, ptr_ctype, lazy_ptr_ctype, + string_ctype, ptr_ctype, ptr_ctype_noderef, lazy_ptr_ctype, incomplete_ctype, label_ctype, bad_ctype, null_ctype; From patchwork Mon Oct 29 15:39:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Dooks X-Patchwork-Id: 10659439 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AAAE417DF for ; Mon, 29 Oct 2018 15:39:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A61CC29AD3 for ; Mon, 29 Oct 2018 15:39:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9A5D829AD7; Mon, 29 Oct 2018 15:39:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CFB7229AD3 for ; Mon, 29 Oct 2018 15:39:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727545AbeJ3A3E (ORCPT ); Mon, 29 Oct 2018 20:29:04 -0400 Received: from imap1.codethink.co.uk ([176.9.8.82]:59236 "EHLO imap1.codethink.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727520AbeJ3A3D (ORCPT ); Mon, 29 Oct 2018 20:29:03 -0400 Received: from [148.252.241.226] (helo=rainbowdash) by imap1.codethink.co.uk with esmtpsa (Exim 4.84_2 #1 (Debian)) id 1gH9dx-0005vP-Vb; Mon, 29 Oct 2018 15:39:54 +0000 Received: from ben by rainbowdash with local (Exim 4.91) (envelope-from ) id 1gH9dx-0003eY-LJ; Mon, 29 Oct 2018 15:39:53 +0000 From: Ben Dooks To: linux-sparse@vger.kernel.org Cc: Ben Dooks Subject: [PATCH 3/5] initial parsing of __attribute__((format)) Date: Mon, 29 Oct 2018 15:39:50 +0000 Message-Id: <20181029153952.13927-4-ben.dooks@codethink.co.uk> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181029153952.13927-1-ben.dooks@codethink.co.uk> References: <20181029153952.13927-1-ben.dooks@codethink.co.uk> MIME-Version: 1.0 Sender: linux-sparse-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sparse@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add code to parse the __attribute__((format)) used to indicate that a variadic function takes a printf-style format string and where those are. Save the data in ctype ready for checking when such an function is encoutered. Signed-off-by: Ben Dooks --- Fixes since v1: - moved to using ctype in base_type to store infromation - fixed formatting issues - updated check for bad format arguments - reduced the line count to unsigned short to save space Notes: - What to do when base_type is not set... current code doesn't work --- parse.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- symbol.h | 2 ++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/parse.c b/parse.c index 02a55a7..9b0d40e 100644 --- a/parse.c +++ b/parse.c @@ -84,7 +84,7 @@ static attr_t attribute_address_space, attribute_context, attribute_designated_init, attribute_transparent_union, ignore_attribute, - attribute_mode, attribute_force; + attribute_mode, attribute_force, attribute_format; typedef struct symbol *to_mode_t(struct symbol *); @@ -353,6 +353,10 @@ static struct symbol_op attr_force_op = { .attribute = attribute_force, }; +static struct symbol_op attr_format = { + .attribute = attribute_format, +}; + static struct symbol_op address_space_op = { .attribute = attribute_address_space, }; @@ -407,6 +411,10 @@ static struct symbol_op mode_word_op = { .to_mode = to_word_mode }; +static struct symbol_op attr_printf_op = { + .type = KW_FORMAT, +}; + /* Using NS_TYPEDEF will also make the keyword a reserved one */ static struct init_keyword { const char *name; @@ -513,6 +521,8 @@ static struct init_keyword { { "bitwise", NS_KEYWORD, MOD_BITWISE, .op = &attr_bitwise_op }, { "__bitwise__",NS_KEYWORD, MOD_BITWISE, .op = &attr_bitwise_op }, { "address_space",NS_KEYWORD, .op = &address_space_op }, + { "format", NS_KEYWORD, .op = &attr_format }, + { "printf", NS_KEYWORD, .op = &attr_printf_op }, { "mode", NS_KEYWORD, .op = &mode_op }, { "context", NS_KEYWORD, .op = &context_op }, { "designated_init", NS_KEYWORD, .op = &designated_init_op }, @@ -1051,6 +1061,67 @@ static struct token *attribute_address_space(struct token *token, struct symbol return token; } +static struct token *attribute_format(struct token *token, struct symbol *attr, struct decl_state *ctx) +{ + struct expression *args[3]; + struct symbol *fmt_sym = NULL; + int argc = 0; + + /* expecting format ( type, start, va_args at) */ + + token = expect(token, '(', "after format attribute"); + while (!match_op(token, ')')) { + struct expression *expr = NULL; + + if (argc == 0) { + if (token_type(token) == TOKEN_IDENT) + fmt_sym = lookup_keyword(token->ident, NS_KEYWORD); + + if (!fmt_sym || !fmt_sym->op || + fmt_sym->op != &attr_printf_op) { + sparse_error(token->pos, + "unknown format type '%s'\n", + show_ident(token->ident)); + fmt_sym = NULL; + } + } + + token = conditional_expression(token, &expr); + if (!expr) + break; + if (argc < 3) + args[argc++] = expr; + if (!match_op(token, ',')) + break; + token = token->next; + } + + if (argc != 3 || !fmt_sym) { + warning(token->pos, "incorrect format attribute"); + } else { + long long start, at; + + start = get_expression_value(args[2]); + at = get_expression_value(args[1]); + + if (start <= 0 || at <= 0 || (start == at && start > 0)) { + warning(token->pos, "bad format positions"); + } else if (start < at) { + warning(token->pos, "format cannot be after va_args"); + } else if (!ctx->ctype.base_type) { + warning(token->pos, "no base type to set"); + ctx->ctype.printf_va_start = start; + ctx->ctype.printf_msg = at; + } else { + ctx->ctype.base_type->ctype.printf_va_start = start; + ctx->ctype.base_type->ctype.printf_msg = at; + } + } + + token = expect(token, ')', "after format attribute"); + return token; +} + static struct symbol *to_QI_mode(struct symbol *ctype) { if (ctype->ctype.base_type != &int_type) @@ -2102,7 +2173,6 @@ static struct statement *start_function(struct symbol *sym) // Currently parsed symbol for __func__/__FUNCTION__/__PRETTY_FUNCTION__ current_fn = sym; - return stmt; } diff --git a/symbol.h b/symbol.h index 1f338f5..4cd8d61 100644 --- a/symbol.h +++ b/symbol.h @@ -86,6 +86,7 @@ enum keyword { KW_SHORT = 1 << 7, KW_LONG = 1 << 8, KW_EXACT = 1 << 9, + KW_FORMAT = 1 << 10, }; struct context { @@ -103,6 +104,7 @@ struct ctype { struct context_list *contexts; unsigned int as; struct symbol *base_type; + unsigned short printf_va_start, printf_msg; }; struct decl_state { From patchwork Mon Oct 29 15:39:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Dooks X-Patchwork-Id: 10659447 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E18DF17DF for ; Mon, 29 Oct 2018 15:39:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DC76729AAE for ; Mon, 29 Oct 2018 15:39:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D0B9B29AC8; Mon, 29 Oct 2018 15:39:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4BCE029AC7 for ; Mon, 29 Oct 2018 15:39:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727503AbeJ3A3F (ORCPT ); Mon, 29 Oct 2018 20:29:05 -0400 Received: from imap1.codethink.co.uk ([176.9.8.82]:59237 "EHLO imap1.codethink.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727491AbeJ3A3F (ORCPT ); Mon, 29 Oct 2018 20:29:05 -0400 Received: from [148.252.241.226] (helo=rainbowdash) by imap1.codethink.co.uk with esmtpsa (Exim 4.84_2 #1 (Debian)) id 1gH9dy-0005vQ-0r; Mon, 29 Oct 2018 15:39:54 +0000 Received: from ben by rainbowdash with local (Exim 4.91) (envelope-from ) id 1gH9dx-0003eb-MR; Mon, 29 Oct 2018 15:39:53 +0000 From: Ben Dooks To: linux-sparse@vger.kernel.org Cc: Ben Dooks Subject: [PATCH 4/5] evaluate: check variadic argument types against formatting info Date: Mon, 29 Oct 2018 15:39:51 +0000 Message-Id: <20181029153952.13927-5-ben.dooks@codethink.co.uk> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181029153952.13927-1-ben.dooks@codethink.co.uk> References: <20181029153952.13927-1-ben.dooks@codethink.co.uk> MIME-Version: 1.0 Sender: linux-sparse-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sparse@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The variadic argumnet code did not check any of the variadic arguments as it did not previously know the possible type. Now we have the possible formatting information stored in the ctype, we can do some checks on the printf formatting types. Signed-off-by: Ben Dooks --- Fixes since v1: - Split out the format-string -> symbol code - Use symbol_list for the symbols from format parsing - Changed to follow the new parsing code and ctype use - Merged the unsigned-int/long types together Notes: - Is there a way of better doing the vararg list? - %p still generates an address-space mismatch - how do we deal with the kernel's attempt to make printk format all types? --- evaluate.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++-- parse.c | 2 +- 2 files changed, 162 insertions(+), 5 deletions(-) diff --git a/evaluate.c b/evaluate.c index b96696d..2a98a9b 100644 --- a/evaluate.c +++ b/evaluate.c @@ -2243,23 +2243,180 @@ static struct symbol *evaluate_alignof(struct expression *expr) return size_t_ctype; } +struct printf_state { + int len; /* size of the argument (ie, %d, %ld, %lld, etc.) */ +}; + +static struct symbol *evaluate_printf_symbol(const char *string, struct printf_state *state) +{ + struct symbol *sym = NULL; + + switch (string[0]) { + case 'C': + /* TODO - same as lc */ + break; + case 'c': + /* TODO - can take l modifier */ + sym = &char_ctype; + break; + case 'f': + case 'g': + sym = &double_ctype; + break; + case 'h': + /* TODO hh */ + state->len = -1; + break; + case 'j': /* ignore intmax/uintmax for the moment */ + break; + case 'L': + sym = &ldouble_ctype; + break; + case 'l': + state->len++; + break; + case 'p': + /* TODO - deal with void * not being de-referenced in some cases*/ + sym = &ptr_ctype_noderef; + break; + case 'q': + state->len = 2; + break; + case 's': + sym = &string_ctype; + break; + case 'n': + /* TODO - actually pointer to integer */ + sym = &ptr_ctype; + break; + /* note, d is out of alpha order */ + case 'd': + switch (state->len) { + case -1: sym = &short_ctype; break; + case 0: sym = &int_ctype; break; + case 1: sym = &long_ctype; break; + case 2: sym = &llong_ctype; break; + case 3: sym = &lllong_ctype; break; + } + break; + case 'u': + case 'x': + case 'X': + switch (state->len) { + case -1: sym = &ushort_ctype; break; + case 0: sym = &uint_ctype; break; + case 1: sym = &ulong_ctype; break; + case 2: sym = &ullong_ctype; break; + case 3: sym = &ulllong_ctype; break; + } + break; + case 'z': + case 'Z': + sym = &uint_ctype; /* TODO */ + break; + } + + return sym; +} + +static int decompose_format_printf(const char *string, struct symbol_list **result) +{ + struct printf_state state; + int count = 0; + + /* TODO - deal with explitic position arguments */ + for (; string[0] != '\0'; string++) { + struct symbol *sym; + + if (string[0] != '%') + continue; + if (string[1] == '%') { + string++; + continue; + } + + state.len = 0; + + /* get rid of any formatting width bits */ + while (isdigit(string[1]) || string[1] == '+' || string[1] == '-') + string++; + + sym = evaluate_printf_symbol(string+1, &state); + if (sym) { + add_symbol(result, sym); + count++; + } + + while (string[0] != ' ' && string[0] != '\0') + string++; + + string--; + } + + return count; +} + + +static int evaluate_format_printf(struct symbol *fn, struct expression *expr, struct symbol_list **result) +{ + const char *fmt_string = NULL; + int count = -1; + + if (!expr) + return -1; + if (expr->string && expr->string->length) + fmt_string = expr->string->data; + if (!fmt_string) { + struct symbol *sym = evaluate_expression(expr); + + /* attempt to find initialiser for this */ + if (sym && sym->initializer && sym->initializer->string) + fmt_string = sym->initializer->string->data; + } + + if (fmt_string) + count = decompose_format_printf(fmt_string, result); + return count; +} + static int evaluate_arguments(struct symbol *fn, struct expression_list *head) { struct expression *expr; struct symbol_list *argument_types = fn->arguments; + struct symbol_list *variadic_types = NULL; struct symbol *argtype; int i = 1; + /* if we have variadic type info, copy the original arguments + * first so that the format parsing can modify this local set */ + PREPARE_PTR_LIST(argument_types, argtype); FOR_EACH_PTR (head, expr) { struct expression **p = THIS_ADDRESS(expr); - struct symbol *ctype, *target; + struct symbol *ctype, *target = NULL; ctype = evaluate_expression(expr); if (!ctype) return 0; - target = argtype; + if (i == fn->ctype.printf_msg) { + int ret = evaluate_format_printf(fn, *p, &variadic_types); + if (ret < 0) + warning((*p)->pos, "cannot parse format"); + } + + if (i >= fn->ctype.printf_va_start) { + struct symbol *sym; + int arg = i - fn->ctype.printf_va_start; + + FOR_EACH_PTR(variadic_types, sym) { + if (arg == 0) + target = sym; + arg--; + } END_FOR_EACH_PTR(sym); + } else { + target = argtype; + } if (!target) { struct symbol *type; int class = classify_type(ctype, &type); @@ -2281,11 +2438,11 @@ static int evaluate_arguments(struct symbol *fn, struct expression_list *head) sprintf(where, "argument %d", i); compatible_argument_type(expr, target, p, where); } - - i++; NEXT_PTR_LIST(argtype); + i++; } END_FOR_EACH_PTR(expr); FINISH_PTR_LIST(argtype); + return 1; } diff --git a/parse.c b/parse.c index 9b0d40e..6b0a20b 100644 --- a/parse.c +++ b/parse.c @@ -1078,7 +1078,7 @@ static struct token *attribute_format(struct token *token, struct symbol *attr, fmt_sym = lookup_keyword(token->ident, NS_KEYWORD); if (!fmt_sym || !fmt_sym->op || - fmt_sym->op != &attr_printf_op) { + fmt_sym->op->type != KW_FORMAT) { sparse_error(token->pos, "unknown format type '%s'\n", show_ident(token->ident)); From patchwork Mon Oct 29 15:39:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Dooks X-Patchwork-Id: 10659445 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 62B8F4B7E for ; Mon, 29 Oct 2018 15:39:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5FC3129AAE for ; Mon, 29 Oct 2018 15:39:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5418F29AD1; Mon, 29 Oct 2018 15:39:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AD43A29AC8 for ; Mon, 29 Oct 2018 15:39:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727521AbeJ3A3D (ORCPT ); Mon, 29 Oct 2018 20:29:03 -0400 Received: from imap1.codethink.co.uk ([176.9.8.82]:59238 "EHLO imap1.codethink.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727545AbeJ3A3D (ORCPT ); Mon, 29 Oct 2018 20:29:03 -0400 Received: from [148.252.241.226] (helo=rainbowdash) by imap1.codethink.co.uk with esmtpsa (Exim 4.84_2 #1 (Debian)) id 1gH9dy-0005vR-21; Mon, 29 Oct 2018 15:39:54 +0000 Received: from ben by rainbowdash with local (Exim 4.91) (envelope-from ) id 1gH9dx-0003ee-O9; Mon, 29 Oct 2018 15:39:53 +0000 From: Ben Dooks To: linux-sparse@vger.kernel.org Cc: Ben Dooks Subject: [PATCH 5/5] evaluate: stifle check if one pointer is a noderef Date: Mon, 29 Oct 2018 15:39:52 +0000 Message-Id: <20181029153952.13927-6-ben.dooks@codethink.co.uk> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181029153952.13927-1-ben.dooks@codethink.co.uk> References: <20181029153952.13927-1-ben.dooks@codethink.co.uk> MIME-Version: 1.0 Sender: linux-sparse-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sparse@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If both t1 and t2 are ptr_ctype_noderef then it should be ok to ignore the address-space of both (in the case of passing to printf style functions). Signed-off-by: Ben Dooks --- evaluate.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/evaluate.c b/evaluate.c index 2a98a9b..0d5b8ad 100644 --- a/evaluate.c +++ b/evaluate.c @@ -718,7 +718,8 @@ const char *type_difference(struct ctype *c1, struct ctype *c2, /* XXX: we ought to compare sizes */ break; case SYM_PTR: - if (as1 != as2) + if (as1 != as2 && (t1 != &ptr_ctype_noderef && + t2 != &ptr_ctype_noderef)) return "different address spaces"; /* MOD_SPECIFIER is due to idiocy in parse.c */ if ((mod1 ^ mod2) & ~MOD_IGNORE & ~MOD_SPECIFIER)