From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) by sourceware.org (Postfix) with ESMTPS id 44388385840B; Thu, 13 Jan 2022 11:00:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 44388385840B Received: by mail-ed1-x52f.google.com with SMTP id 30so21678268edv.3; Thu, 13 Jan 2022 03:00:48 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language; bh=6TuwukP3FDqUOviZo4qEM9fHug+/syOw5e0AJSBMKf8=; b=Pp48XtUXAqX+gVztOPUv1UZ5TWfzandIPHk0j/z+2QfpnKrCY81KB6j5sX0n5nANeI e6iCXEP7CLKFPTjR7RBVTqTUun7NlOSGS4nrtydjk2bBx8C2It9g8aRKib4doW/hJAcM a16J2CSy9qDYzw6dCiixRCrBGS//7+UQOiaH6FCQIV7VPC/DI8VXTcum2e6AN3fpSoqo BPXeN3b9NTK3X1oXfKO9B5Sc6tu7nh4Dk2w2O7UuCYf7C9k55QA8MMXylg7GUvT6GFF5 Yks2UhhlHSvcZWlRx49lKnKIadxrVGuRpA97M44IGxDeiqWjrq7dl+xbPGivo07DpzTy 1iOQ== X-Gm-Message-State: AOAM5326IRiRW79SL5rIjb8jsz8bX1Bm8QMJT45XSTjiTYmpnPuv2eZ0 h8f6Ad+MyYivUbj4N3FQOBhHpgBmWGs= X-Google-Smtp-Source: ABdhPJx2gu0gD3+0RMsNJ0gf1iGCcQDJQVgvC7ac96uzlPmZHim9DrNpY//oPiGTQN1L8C9VhhgsMQ== X-Received: by 2002:a17:906:f2c8:: with SMTP id gz8mr1665532ejb.220.1642071647095; Thu, 13 Jan 2022 03:00:47 -0800 (PST) Received: from [192.168.0.87] (ip-86-49-13-224.net.upcbroadband.cz. [86.49.13.224]) by smtp.gmail.com with ESMTPSA id x11sm1007897edq.55.2022.01.13.03.00.46 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 13 Jan 2022 03:00:46 -0800 (PST) Subject: Re: [PATCH] [12/11/10] Fix invalid format warnings on Windows To: =?UTF-8?Q?Martin_Li=c5=a1ka?= , gcc-patches@gcc.gnu.org Cc: joseph@codesourcery.com, martin@martin.st, redi@gcc.gnu.org References: <466c29c3-54b1-5627-3d9d-e385ad037a4e@suse.cz> <7fd8d3fb-e0c6-decc-374f-495ab81ab1ff@gmail.com> From: Tomas Kalibera Message-ID: Date: Thu, 13 Jan 2022 12:00:45 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.14.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/mixed; boundary="------------72E5FDA1443E176209F340DB" Content-Language: en-US X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, NICE_REPLY_A, 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: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Jan 2022 11:00:50 -0000 This is a multi-part message in MIME format. --------------72E5FDA1443E176209F340DB Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit On 1/13/22 10:40 AM, Martin Liška wrote: [...] > Apart from that, I support the patch (I cannot approve it). Note we're > now approaching > stage4 and this is definitelly a stage1 material (opens after GCC > 12.1.0 gets released). Thanks, Martin, I've updated the patch following your suggestions. Cheers Tomas > > Cheers, > Martin > --------------72E5FDA1443E176209F340DB Content-Type: text/x-patch; charset=UTF-8; name="0001-c-family-Let-stdio.h-override-built-in-printf-format.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-c-family-Let-stdio.h-override-built-in-printf-format.pa"; filename*1="tch" >From 4db4e6b35be5793902d8820d2c8e4d1f1cbba80d Mon Sep 17 00:00:00 2001 From: Tomas Kalibera Date: Thu, 13 Jan 2022 05:25:32 -0500 Subject: [PATCH] c-family: Let stdio.h override built in printf format [PR95130,PR92292] Mingw32 targets use ms_printf format for printf, but mingw-w64 when configured for UCRT uses gnu_format (via stdio.h). GCC then checks both formats, which means that one cannot print a 64-bit integer without a warning. All these lines issue a warning: printf("Hello %"PRIu64"\n", x); printf("Hello %I64u\n", x); printf("Hello %llu\n", x); because each of them violates one of the formats. Also, one gets a warning twice if the format string violates both formats. Fixed by disabling the built in format in case there are additional ones. gcc/c-family/ChangeLog: PR c/95130 PR c/92292 * c-common.c (check_function_arguments): Pass also function declaration to check_function_format. * c-common.h (check_function_format): Extra argument - function declaration. * c-format.c (check_function_format): For builtin functions with a built in format and at least one more, do not check the first one. --- gcc/c-family/c-common.c | 2 +- gcc/c-family/c-common.h | 2 +- gcc/c-family/c-format.c | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 4a6a4edb763..00fc734d28e 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -6064,7 +6064,7 @@ check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype, /* Check for errors in format strings. */ if (warn_format || warn_suggest_attribute_format) - check_function_format (fntype, TYPE_ATTRIBUTES (fntype), nargs, argarray, + check_function_format (fndecl, fntype, TYPE_ATTRIBUTES (fntype), nargs, argarray, arglocs); if (warn_format) diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 8b7bf35e888..ee370eafbbc 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -856,7 +856,7 @@ extern void check_function_arguments_recurse (void (*) unsigned HOST_WIDE_INT); extern bool check_builtin_function_arguments (location_t, vec, tree, tree, int, tree *); -extern void check_function_format (const_tree, tree, int, tree *, +extern void check_function_format (const_tree, const_tree, tree, int, tree *, vec *); extern bool attribute_fallthrough_p (tree); extern tree handle_format_attribute (tree *, tree, tree, int, bool *); diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c index afa77810a5c..bc2abee5146 100644 --- a/gcc/c-family/c-format.c +++ b/gcc/c-family/c-format.c @@ -1160,12 +1160,13 @@ decode_format_type (const char *s, bool *is_raw /* = NULL */) attribute themselves. */ void -check_function_format (const_tree fntype, tree attrs, int nargs, +check_function_format (const_tree fndecl, const_tree fntype, tree attrs, int nargs, tree *argarray, vec *arglocs) { - tree a; + tree a, aa; tree atname = get_identifier ("format"); + bool skipped_default_format = false; /* See if this function has any format attributes. */ for (a = attrs; a; a = TREE_CHAIN (a)) @@ -1176,6 +1177,33 @@ check_function_format (const_tree fntype, tree attrs, int nargs, function_format_info info; decode_format_attr (fntype, atname, TREE_VALUE (a), &info, /*validated=*/true); + + /* Mingw32 targets have traditionally used ms_printf format for the + printf function, and this format is built in GCC. But nowadays, + if mingw-w64 is configured to target UCRT, the printf function + uses the gnu_printf format (specified in the stdio.h header). This + causes GCC to check both formats, which means that there is no way + to e.g. print a long long unsigned without a warning (ms_printf + warns for %llu and gnu_printf warns for %I64u). Also, GCC would warn + twice about the same issue when both formats are violated, e.g. + for %lu used to print long long unsigned. + + Hence, if there are multiple format specifiers, we skip the first + one. See PR 95130, PR 92292. */ + + if (!skipped_default_format && fndecl) + { + for(aa = TREE_CHAIN (a); aa; aa = TREE_CHAIN(aa)) + if (is_attribute_p ("format", get_attribute_name (aa)) && + fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)) + { + skipped_default_format = true; + break; + } + if (skipped_default_format) + continue; + } + if (warn_format) { /* FIXME: Rewrite all the internal functions in this file -- 2.25.1 --------------72E5FDA1443E176209F340DB--