From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31589 invoked by alias); 20 Jul 2012 12:58:10 -0000 Received: (qmail 31579 invoked by uid 22791); 20 Jul 2012 12:58:09 -0000 X-SWARE-Spam-Status: No, hits=-4.3 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00,KHOP_THREADED,TW_CF X-Spam-Check-By: sourceware.org Received: from localhost (HELO gcc.gnu.org) (127.0.0.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 20 Jul 2012 12:57:56 +0000 From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/54046] [4.6/4.7/4.8 Regression] wrong control reaches end of non-void function for switch case with throw and default Date: Fri, 20 Jul 2012 12:58:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Keywords: diagnostic X-Bugzilla-Severity: normal X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: CC Message-ID: In-Reply-To: References: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2012-07/txt/msg01619.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54046 Jakub Jelinek changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #3 from Jakub Jelinek 2012-07-20 12:57:42 UTC --- Or: void foo (void) __attribute__((noreturn)); void bar (void); struct A { ~A () {} }; bool check (int x) { A z; switch (x) { case 0: return false; default: foo (); bar (); } } The problem is related to pass ordering. EH lowering is done before CFG cleanups, so if there is code after a noreturn spot (whether throw or noreturn function, endless loop etc. doesn't matter), when trying to lower try .. finally EH will see gimple_seq_may_fallthru to be true because of the extra code after it hiding that it in fact can't fall thru. We end up then with: switch (x) , case 0: > : D.2216 = 0; finally_tmp.0 = 0; goto ; : foo (); bar (); finally_tmp.0 = 1; : A::~A (&z); switch (finally_tmp.0) , default: , case 1: > where D.2221 falls thru to exit without returning a value, while D.2223 doesn't. Then cfg cleanup during cfg pass cleans that up to: finally_tmp.0 = 0; A::~A (&z); switch (finally_tmp.0) , case 1: > after finding out that foo is noreturn and can't fallthru. But there is no constant propagation and switch optimization pass that would simplify switch (0) into goto something; scheduled before the pass_warn_function_return is scheduled. As we aren't in SSA form at that point, doing it wouldn't be very easy.