From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 105882 invoked by alias); 13 Mar 2019 10:18:35 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 105752 invoked by uid 89); 13 Mar 2019 10:18:35 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.1 spammy=divide, H*M:d820, preferences, H*MI:sk:2019031 X-HELO: mailfilter05.hatteland.com Received: from mailfilter05.hatteland.com (HELO mailfilter05.hatteland.com) (213.162.250.24) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 13 Mar 2019 10:18:27 +0000 Subject: Re: GCC turns &~ into | due to undefined bit-shift without warning To: References: <4af9e251-f4c3-a5a4-e33d-fb8750c87e36@redheads.de> <20190311091449.GB7611@tucnak> <9085342b-41a6-851c-28e3-08a40cc30103@redheads.de> <20190311112429.GA377@cventin.lip.ens-lyon.fr> <0474f7ad-1e8d-e545-ff36-1f5c122aabfd@westcontrol.com> <20190312154013.GA9898@cventin.lip.ens-lyon.fr> <20190313022539.GA28438@zira.vinc17.org> From: David Brown Openpgp: preference=signencrypt Message-ID: <5aeec750-d820-ce56-bd27-6271dc23ac4d@westcontrol.com> Date: Wed, 13 Mar 2019 10:18:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.4.0 MIME-Version: 1.0 In-Reply-To: <20190313022539.GA28438@zira.vinc17.org> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-TMASE-Result: 10--13.777800-8.000000 X-TMASE-Version: SMEX-12.5.0.1300-8.5.1010-24486.006 X-C2ProcessedOrg: 4211b608-5821-4111-aa64-134b1f19f522 X-SW-Source: 2019-03/txt/msg00107.txt.bz2 On 13/03/2019 03:25, Vincent Lefevre wrote: > On 2019-03-12 21:56:59 +0100, David Brown wrote: >> I disagree. To generate an unconditional error (rejecting the program), the >> compiler would need such proof - such as by tracing execution from main(). >> But to generate a warning activated specifically by the user, there is no >> such requirement. It's fine to give a warning based on the code written, >> rather than on code that the compiler knows without doubt will be executed. > > There's already a bug about spurious warnings on shift counts: > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210 > You can divide code into three groups (with the exact divisions varying by compiler switches and version): 1. Code that the compiler knows for sure will run in every execution of the program, generally because it can track the code flow from main(). 2. Code that the compiler knows will /not/ run, due to things like constant propagation, inlining, etc. 3. Code that the compiler does not know if it will run or not. Code in group 1 here is usually quite small. Code in group 2 can be large, especially with C++ header libraries, templates, etc. The compiler will often eliminate such code and avoid generating any object code. gcc used to have a warning for when it found "group 2" code and eliminated it - that warning was removed as gcc got smarter, and the false positives were overwhelming. Most code is in group 3. I would say that if the compiler finds undefined behaviour in group 1 code, it should give an unconditional error message, almost regardless of compiler switches. (Many people will disagree with me here - that's okay. Fortunately for everyone else, I am not the one who decides these things in gcc!). Certainly that is standards-condoned behaviour. To be useful to the developer, warnings have to be applied to group 3 code. That does mean a risk of false positives - some code will be group 2 (never run) though the compiler doesn't know it. I am arguing here that a warning like this should be applied to group 3 code - you are suggesting it should only apply to group 1. The bug report you linked was for code in group 2 - code that the compiler can (or should be able to) see is never run. I can see it makes sense to disable or hide warnings from such code, but it may be useful to have them anyway. I expect people to have different preferences here. (I see in that bug report, solutions are complicated because C lets you "disable" a block by writing "if (0)", and then lets you jump into it from outside with labels and goto's. Perhaps that should automatically trigger a warning saying "Your code is made of spaghetti. Any other warnings may be unreliable with many false positives and false negatives".)