From patchwork Wed Feb 23 08:14:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 51318 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 485493947C2E for ; Wed, 23 Feb 2022 08:15:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 485493947C2E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1645604122; bh=8I3c/aBeHvkAsw5E9LFkRvfdYQ7EwY6Mfr83K2erPS8=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=G0EcUwJS+vFaSx52AuvXJtjPBXznUSiE8rGCcW6tm99P4lTX6+bA8KeEzH/Ysw4Ck qTHSuotA/05RHSfwxlShPRvmrnKd3xjN4c6Fyxd0oaAPZURw1FNMiqH48DEtbuDimr 6rBXg+30/Fq3VJM1klRl9kGMDRNY7+qgnkFDOzO0= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 7A96D3947422 for ; Wed, 23 Feb 2022 08:14:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7A96D3947422 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-371-WfmUiin_NVq1aGdupkYCNA-1; Wed, 23 Feb 2022 03:14:32 -0500 X-MC-Unique: WfmUiin_NVq1aGdupkYCNA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8BA1D1006AA5; Wed, 23 Feb 2022 08:14:31 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.125]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 24E0F104810D; Wed, 23 Feb 2022 08:14:30 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.16.1/8.16.1) with ESMTPS id 21N8ESo22360690 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Wed, 23 Feb 2022 09:14:28 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.16.1/8.16.1/Submit) id 21N8ERh52360689; Wed, 23 Feb 2022 09:14:27 +0100 Date: Wed, 23 Feb 2022 09:14:27 +0100 To: Richard Biener , Jeff Law Subject: [PATCH] warn-recursion: Don't warn for __builtin_calls in gnu_inline extern inline functions [PR104633] Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-5.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Cc: gcc-patches@gcc.gnu.org, Martin Sebor Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi! The first two testcases show different ways how e.g. the glibc _FORTIFY_SOURCE wrappers are implemented, and on Winfinite-recursion-3.c the new -Winfinite-recursion warning emits a false positive warning. It is a false positive because when a builtin with 2 names is called through the __builtin_ name (but not all builtins have a name prefixed exactly like that) from extern inline function with gnu_inline semantics, it doesn't mean the compiler will ever attempt to use the user inline wrapper for the call, the __builtin_ just does what the builtin function is expected to do and either expands into some compiler generated code, or if the compiler decides to emit a call it will use an actual definition of the function, but that is not the extern inline gnu_inline function which is never emitted out of line. Compared to that, in Winfinite-recursion-5.c the extern inline gnu_inline wrapper calls the builtin by the same name as the function's name and in that case it is infinite recursion, we actuall try to inline the recursive call and also error because the recursion is infinite during inlining; without always_inline we wouldn't error but it is still infinite recursion, the user has no control on how many recursive calls we actually inline. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2022-02-22 Jakub Jelinek PR c/104633 * gimple-warn-recursion.cc (pass_warn_recursion::find_function_exit): Don't warn about calls to corresponding builtin from extern inline gnu_inline wrappers. * gcc.dg/Winfinite-recursion-3.c: New test. * gcc.dg/Winfinite-recursion-4.c: New test. * gcc.dg/Winfinite-recursion-5.c: New test. Jakub --- gcc/gimple-warn-recursion.cc.jj 2022-01-18 11:58:59.619981528 +0100 +++ gcc/gimple-warn-recursion.cc 2022-02-22 13:19:43.592644576 +0100 @@ -112,13 +112,25 @@ pass_warn_recursion::find_function_exit if (!strcmp (name, "siglongjmp")) return true; - if (m_built_in && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL) + if (m_built_in + && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL) && m_built_in == DECL_FUNCTION_CODE (fndecl)) { - /* The call is being made from the definition of a built-in - (e.g., in a replacement of one) to itself. */ - m_calls->safe_push (stmt); - return false; + const char *cname + = IDENTIFIER_POINTER (DECL_NAME (current_function_decl)); + /* Don't warn about gnu_inline extern inline function + like strcpy calling __builtin_strcpy, that is fine, + if some call is made (the builtin isn't expanded inline), + a call is made to the external definition. */ + if (!(DECL_DECLARED_INLINE_P (current_function_decl) + && DECL_EXTERNAL (current_function_decl)) + || strcmp (name, cname) == 0) + { + /* The call is being made from the definition of a built-in + (e.g., in a replacement of one) to itself. */ + m_calls->safe_push (stmt); + return false; + } } } --- gcc/testsuite/gcc.dg/Winfinite-recursion-3.c.jj 2022-02-22 13:28:10.345579876 +0100 +++ gcc/testsuite/gcc.dg/Winfinite-recursion-3.c 2022-02-22 13:25:16.760999396 +0100 @@ -0,0 +1,18 @@ +/* PR c/104633 */ +/* { dg-do compile } */ +/* { dg-options "-Winfinite-recursion" } */ + +typedef __SIZE_TYPE__ size_t; +int memcmp (const void *, const void *, size_t); + +extern inline __attribute__((always_inline, gnu_inline)) int +memcmp (const void *p, const void *q, size_t size) /* { dg-bogus "infinite recursion detected" } */ +{ + return __builtin_memcmp (p, q, size); /* { dg-bogus "recursive call" } */ +} + +int +foo (const void *p, const void *q, size_t size) +{ + return memcmp (p, q, size); +} --- gcc/testsuite/gcc.dg/Winfinite-recursion-4.c.jj 2022-02-22 13:28:13.604534458 +0100 +++ gcc/testsuite/gcc.dg/Winfinite-recursion-4.c 2022-02-22 13:25:22.552918640 +0100 @@ -0,0 +1,19 @@ +/* PR c/104633 */ +/* { dg-do compile } */ +/* { dg-options "-Winfinite-recursion" } */ + +typedef __SIZE_TYPE__ size_t; +int memcmp (const void *, const void *, size_t); +__typeof (memcmp) __memcmp_alias __asm ("memcmp"); + +extern inline __attribute__((always_inline, gnu_inline)) int +memcmp (const void *p, const void *q, size_t size) /* { dg-bogus "infinite recursion detected" } */ +{ + return __memcmp_alias (p, q, size); /* { dg-bogus "recursive call" } */ +} + +int +foo (const void *p, const void *q, size_t size) +{ + return memcmp (p, q, size); +} --- gcc/testsuite/gcc.dg/Winfinite-recursion-5.c.jj 2022-02-22 13:28:16.690491449 +0100 +++ gcc/testsuite/gcc.dg/Winfinite-recursion-5.c 2022-02-22 13:27:13.024378761 +0100 @@ -0,0 +1,18 @@ +/* PR c/104633 */ +/* { dg-do compile } */ +/* { dg-options "-Winfinite-recursion" } */ + +typedef __SIZE_TYPE__ size_t; +int memcmp (const void *, const void *, size_t); + +extern inline __attribute__((always_inline, gnu_inline)) int +memcmp (const void *p, const void *q, size_t size) /* { dg-warning "infinite recursion detected" } */ +{ /* { dg-error "inlining failed in call to" "" { target *-*-* } .-1 } */ + return memcmp (p, q, size); /* { dg-message "recursive call" } */ +} /* { dg-message "called from here" "" { target *-*-* } .-1 } */ + +int +foo (const void *p, const void *q, size_t size) +{ + return memcmp (p, q, size); +}