From patchwork Wed Sep 22 00:31:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 45262 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6F845385841C for ; Wed, 22 Sep 2021 00:31:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6F845385841C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1632270703; bh=tbygJF3aQMmcHyIHSMsg3L4tDmacp6r6Yf7VBsz6vT0=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=WKrPhaTcgnbPSez6D52lGVUgkOVdpXc4uGotlUn1FYyHooPn3fb7+R2q55df0YmOU 9u7AeaFgM9C6CUZpFkMclmZ7aNTj4oc/DguRhefpSkD4yyAHaPeD7+J07dpImQ8rYr vCq1etDuZTIWR7gdEStxpilFCtAWHk/QCIAPBSj4= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qk1-x730.google.com (mail-qk1-x730.google.com [IPv6:2607:f8b0:4864:20::730]) by sourceware.org (Postfix) with ESMTPS id 5FF5B3858D39 for ; Wed, 22 Sep 2021 00:31:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5FF5B3858D39 Received: by mail-qk1-x730.google.com with SMTP id b65so3341103qkc.13 for ; Tue, 21 Sep 2021 17:31:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version:content-language; bh=tbygJF3aQMmcHyIHSMsg3L4tDmacp6r6Yf7VBsz6vT0=; b=Qd3Vvz2DQSUa4YloY2wwCSx6vRoUl0O2hvl26sfMKurd1q78Ol0w9UfvIsnOr4qVUE jYHsZ15OSjBUvvWafx95JgdbrOjkaWtD1Qou9TjfOcY47VQyyrihsosFB6nza3kf7Si+ X5zhNvc+pqq3usR2GbZqvPJUD6fa2JjnWZhkAXgJel1VRz6o7+J766NYmkbenJU5AJnh v/xNCgH10tgYndsF5unohuox5kiV//IyDVX+kOCfQ8rytz9Q996oaIHDqIyAGj6Abxxs MeFOLjgPIXExe2PDkZayBRANJxZu3kANt75jVQ96l76UPADMtzJB5eSxi5pVeTKtxHrR Mn/A== X-Gm-Message-State: AOAM533fuMGsAuHc2eRwCWosryJva7PdzhoxLYggsxX0MnYV5f+U8JMA cPdoB2Lf5O0OiXmQ1BLqoM988p5phhg= X-Google-Smtp-Source: ABdhPJyrwqnDot6fLgM7qM3AUcCcl+62v0MEEHobqlv4pza88a4Yn/Kj6gvim0HT+4k70oX7mR9cZg== X-Received: by 2002:a37:96c2:: with SMTP id y185mr31258755qkd.6.1632270679906; Tue, 21 Sep 2021 17:31:19 -0700 (PDT) Received: from [192.168.0.41] (97-118-96-133.hlrn.qwest.net. [97.118.96.133]) by smtp.gmail.com with ESMTPSA id 66sm494518qke.118.2021.09.21.17.31.19 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 21 Sep 2021 17:31:19 -0700 (PDT) To: GNU C Library Subject: avoid -Waddress in vfprintf-internal.c Message-ID: <14db3354-56a5-86cc-b840-010c9ba7fc83@gmail.com> Date: Tue, 21 Sep 2021 18:31:18 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-10.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Martin Sebor via Libc-alpha From: Martin Sebor Reply-To: Martin Sebor Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Building Glibc with a GCC 12 enhanced to detect more instances of comparing addresses to null that are guaranteed to evaluate to a constanst triggers a large number of such instancesl. The warnings, all isolated to the same file, are valid and intended but the Glibc code is safe. They show up because the comparison is in a macro to which either null or a constant address of an array element are alternately passed as an argument. The attached patch avoids these warnings by introducing local variables for the address being compared (an array element) as well as for the null pointer. Tested by building Glibc on x86_64, verifying the warnings are gone, and by running the testsuite and checking for new failures. Martin diff --git a/stdio-common/vfprintf-internal.c b/stdio-common/vfprintf-internal.c index 3f3d1e148a..1a9f94e930 100644 --- a/stdio-common/vfprintf-internal.c +++ b/stdio-common/vfprintf-internal.c @@ -1447,6 +1447,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap, unsigned int mode_flags) UCHAR_T pad = L_(' ');/* Padding character. */ CHAR_T spec; + /* Passed to the process_arg macro instead of NULL to avoid -Waddress. */ + struct printf_spec * null_pspec = NULL; + workend = work_buffer + WORK_BUFFER_SIZE; /* Get current character in format string. */ @@ -1643,8 +1646,8 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap, unsigned int mode_flags) /* Process current format. */ while (1) { - process_arg (((struct printf_spec *) NULL)); - process_string_arg (((struct printf_spec *) NULL)); + process_arg (null_pspec); + process_string_arg (null_pspec); LABEL (form_unknown): if (spec == L_('\0')) @@ -1904,53 +1907,55 @@ printf_positional (FILE *s, const CHAR_T *format, int readonly_format, union printf_arg the_arg; CHAR_T *string; /* Pointer to argument string. */ + struct printf_spec * const pspec = &specs[nspecs_done]; + /* Fill variables from values in struct. */ - int alt = specs[nspecs_done].info.alt; - int space = specs[nspecs_done].info.space; - int left = specs[nspecs_done].info.left; - int showsign = specs[nspecs_done].info.showsign; - int group = specs[nspecs_done].info.group; - int is_long_double = specs[nspecs_done].info.is_long_double; - int is_short = specs[nspecs_done].info.is_short; - int is_char = specs[nspecs_done].info.is_char; - int is_long = specs[nspecs_done].info.is_long; - int width = specs[nspecs_done].info.width; - int prec = specs[nspecs_done].info.prec; - int use_outdigits = specs[nspecs_done].info.i18n; - char pad = specs[nspecs_done].info.pad; - CHAR_T spec = specs[nspecs_done].info.spec; + int alt = pspec->info.alt; + int space = pspec->info.space; + int left = pspec->info.left; + int showsign = pspec->info.showsign; + int group = pspec->info.group; + int is_long_double = pspec->info.is_long_double; + int is_short = pspec->info.is_short; + int is_char = pspec->info.is_char; + int is_long = pspec->info.is_long; + int width = pspec->info.width; + int prec = pspec->info.prec; + int use_outdigits = pspec->info.i18n; + char pad = pspec->info.pad; + CHAR_T spec = pspec->info.spec; CHAR_T *workend = work_buffer + WORK_BUFFER_SIZE; /* Fill in last information. */ - if (specs[nspecs_done].width_arg != -1) + if (pspec->width_arg != -1) { /* Extract the field width from an argument. */ - specs[nspecs_done].info.width = - args_value[specs[nspecs_done].width_arg].pa_int; + pspec->info.width = + args_value[pspec->width_arg].pa_int; - if (specs[nspecs_done].info.width < 0) + if (pspec->info.width < 0) /* If the width value is negative left justification is selected and the value is taken as being positive. */ { - specs[nspecs_done].info.width *= -1; - left = specs[nspecs_done].info.left = 1; + pspec->info.width *= -1; + left = pspec->info.left = 1; } - width = specs[nspecs_done].info.width; + width = pspec->info.width; } - if (specs[nspecs_done].prec_arg != -1) + if (pspec->prec_arg != -1) { /* Extract the precision from an argument. */ - specs[nspecs_done].info.prec = - args_value[specs[nspecs_done].prec_arg].pa_int; + pspec->info.prec = + args_value[pspec->prec_arg].pa_int; - if (specs[nspecs_done].info.prec < 0) + if (pspec->info.prec < 0) /* If the precision is negative the precision is omitted. */ - specs[nspecs_done].info.prec = -1; + pspec->info.prec = -1; - prec = specs[nspecs_done].info.prec; + prec = pspec->info.prec; } /* Process format specifiers. */ @@ -1963,17 +1968,17 @@ printf_positional (FILE *s, const CHAR_T *format, int readonly_format, && __printf_function_table != NULL && __printf_function_table[(size_t) spec] != NULL) { - const void **ptr = alloca (specs[nspecs_done].ndata_args + const void **ptr = alloca (pspec->ndata_args * sizeof (const void *)); /* Fill in an array of pointers to the argument values. */ - for (unsigned int i = 0; i < specs[nspecs_done].ndata_args; + for (unsigned int i = 0; i < pspec->ndata_args; ++i) - ptr[i] = &args_value[specs[nspecs_done].data_arg + i]; + ptr[i] = &args_value[pspec->data_arg + i]; /* Call the function. */ function_done = __printf_function_table[(size_t) spec] - (s, &specs[nspecs_done].info, ptr); + (s, &pspec->info, ptr); if (function_done != -2) { @@ -1993,23 +1998,23 @@ printf_positional (FILE *s, const CHAR_T *format, int readonly_format, JUMP (spec, step4_jumps); - process_arg ((&specs[nspecs_done])); - process_string_arg ((&specs[nspecs_done])); + process_arg (pspec); + process_string_arg (pspec); LABEL (form_unknown): { unsigned int i; const void **ptr; - ptr = alloca (specs[nspecs_done].ndata_args + ptr = alloca (pspec->ndata_args * sizeof (const void *)); /* Fill in an array of pointers to the argument values. */ - for (i = 0; i < specs[nspecs_done].ndata_args; ++i) - ptr[i] = &args_value[specs[nspecs_done].data_arg + i]; + for (i = 0; i < pspec->ndata_args; ++i) + ptr[i] = &args_value[pspec->data_arg + i]; /* Call the function. */ - function_done = printf_unknown (s, &specs[nspecs_done].info, + function_done = printf_unknown (s, &pspec->info, ptr); /* If an error occurred we don't have information about # @@ -2027,9 +2032,7 @@ printf_positional (FILE *s, const CHAR_T *format, int readonly_format, } /* Write the following constant string. */ - outstring (specs[nspecs_done].end_of_fmt, - specs[nspecs_done].next_fmt - - specs[nspecs_done].end_of_fmt); + outstring (pspec->end_of_fmt, pspec->next_fmt - pspec->end_of_fmt); } all_done: scratch_buffer_free (&argsbuf);