From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21651 invoked by alias); 6 Oct 2017 20:50:43 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 21639 invoked by uid 89); 6 Oct 2017 20:50:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=no version=3.3.2 spammy= X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 06 Oct 2017 20:50:41 +0000 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2C3266147B; Fri, 6 Oct 2017 20:50:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 2C3266147B Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=law@redhat.com Received: from localhost.localdomain (ovpn-112-15.rdu2.redhat.com [10.10.112.15]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6AA845D9C9; Fri, 6 Oct 2017 20:50:36 +0000 (UTC) Subject: Re: [RFA] [PATCH] Add a warning for invalid function casts To: Martin Sebor , Bernd Edlinger , "gcc-patches@gcc.gnu.org" References: <1644e85e-6d3a-a114-32b5-a9b49de24407@gmail.com> <72167c17-48f5-d5d6-d9cd-87004e3c1d11@gmail.com> From: Jeff Law Message-ID: Date: Fri, 06 Oct 2017 21:01:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 In-Reply-To: <72167c17-48f5-d5d6-d9cd-87004e3c1d11@gmail.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-IsSubscribed: yes X-SW-Source: 2017-10/txt/msg00409.txt.bz2 On 10/06/2017 09:43 AM, Martin Sebor wrote: > On 10/06/2017 07:25 AM, Bernd Edlinger wrote: >> On 10/05/17 18:16, Martin Sebor wrote: >>> In my (very quick) tests the warning appears to trigger on all >>> strictly incompatible conversions, even if they are otherwise >>> benign, such as: >>> >>>    int f (const int*); >>>    typedef int F (int*); >>> >>>    F* pf1 = f;        // -Wincompatible-pointer-types >>>    F* pf2 = (F*)f;    // -Wcast-function-type >>> >>> Likewise by: >>> >>>    int f (signed char); >>>    typedef int F (unsigned char); >>> >>>    F* pf = (F*)f;    // -Wcast-function-type >>> >>> I'd expect these conversions to be useful and would view warning >>> for them with -Wextra as excessive.  In fact, I'm not sure I see >>> the benefit of warning on these casts under any circumstances. >>> >> >> Well, while the first example should be safe, >> the second one is probably not safe: >> >> Because the signed and unsigned char are promoted to int, >> by the ABI but one is in the range -128..127 while the >> other is in the range 0..255, right? > > Right.  The cast is always safe but whether or not a call to such > a function through the incompatible pointer is also safe depends > on the definition of the function (and on the caller).  If the > function uses just the low bits of the argument then it's most > likely fine for any argument.  If the caller only calls it with > values in the 7-bit range (e.g., the ASCII subset) then it's also > fine.  Otherwise there's the potential for the problem you pointed > out.  (Similarly, if in the first example I gave the cast added > constness to the argument rather than removing it and the function > modified the pointed-to object calling it through the incompatible > pointer on a constant object would also be unsafe.) > > Another class of cases to consider are casts between functions > taking pointers to different but related structs.  Code like this > could be written to mimic C++ calling a base class function on > a derived object. > >   struct Base { ... }; >   struct Derived { Base b; ... }; > >   typedef void F (Derived*); > >   void foo (Base*); > >   F* pf = (F*)foo; Yea. And one might even find such code in BFD. It certainly mimicks C++ base and derived classes using C, so it has significant potential to have this kind of code. jeff