public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* gcc warn unreached else {}
@ 2020-07-09  9:45 Jonny Grant
  2020-07-09 15:00 ` Xi Ruoyao
  2020-07-09 16:15 ` Martin Sebor
  0 siblings, 2 replies; 9+ messages in thread
From: Jonny Grant @ 2020-07-09  9:45 UTC (permalink / raw)
  To: gcc-help

Hello!

There is an example below, (my code is not like this example below). I'm reporting a possible issue, and asking if there is a way to detect it in code bases. If it's a real issue I can file a bug report on Bugzilla.

Can gcc warn where code will not get to the 'return 3;' below?

Cheers, Jonny


int main(void)
{
    const int i = 1;
    if(1 == i)
    {
        return 1;
    }
    else if(1 != i)
    {
        return 2;
    }
    else
    {
        return 3;
    }
}


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: gcc warn unreached else {}
  2020-07-09  9:45 gcc warn unreached else {} Jonny Grant
@ 2020-07-09 15:00 ` Xi Ruoyao
  2020-07-09 15:15   ` Jonny Grant
  2020-07-09 16:15 ` Martin Sebor
  1 sibling, 1 reply; 9+ messages in thread
From: Xi Ruoyao @ 2020-07-09 15:00 UTC (permalink / raw)
  To: Jonny Grant; +Cc: gcc-help

On 2020-07-09 10:45 +0100, Jonny Grant wrote:
> Hello!
> 
> There is an example below, (my code is not like this example below). I'm
> reporting a possible issue, and asking if there is a way to detect it in code
> bases. If it's a real issue I can file a bug report on Bugzilla.
> 
> Can gcc warn where code will not get to the 'return 3;' below?
> 
> Cheers, Jonny
> 
> 
> int main(void)
> {
>     const int i = 1;
>     if(1 == i)
>     {
>         return 1;
>     }
>     else if(1 != i)
>     {
>         return 2;
>     }
>     else
>     {
>         return 3;
>     }
> }

Generally finding all the branches in a program impossible to be executed is
unsolvable.  Even in a program without any loop it's still NP-hard.

For some "simple" cases maybe we can implement some heuristics, or use a brute
force approach (as a part of -fanalyzer).  But I doubt if these simple cases are
really useful.
-- 
Xi Ruoyao <xry111@mengyan1223.wang>
School of Aerospace Science and Technology, Xidian University


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: gcc warn unreached else {}
  2020-07-09 15:00 ` Xi Ruoyao
@ 2020-07-09 15:15   ` Jonny Grant
       [not found]     ` <e20bf113efcb7fe3e533ac694aa4bd62519b3654.camel@mengyan1223.wang>
  0 siblings, 1 reply; 9+ messages in thread
From: Jonny Grant @ 2020-07-09 15:15 UTC (permalink / raw)
  To: Xi Ruoyao; +Cc: gcc-help



On 09/07/2020 16:00, Xi Ruoyao wrote:
> On 2020-07-09 10:45 +0100, Jonny Grant wrote:
>> Hello!
>>
>> There is an example below, (my code is not like this example below). I'm
>> reporting a possible issue, and asking if there is a way to detect it in code
>> bases. If it's a real issue I can file a bug report on Bugzilla.
>>
>> Can gcc warn where code will not get to the 'return 3;' below?
>>
>> Cheers, Jonny
>>
>>
>> int main(void)
>> {
>>     const int i = 1;
>>     if(1 == i)
>>     {
>>         return 1;
>>     }
>>     else if(1 != i)
>>     {
>>         return 2;
>>     }
>>     else
>>     {
>>         return 3;
>>     }
>> }
> 
> Generally finding all the branches in a program impossible to be executed is
> unsolvable.  Even in a program without any loop it's still NP-hard.
> 
> For some "simple" cases maybe we can implement some heuristics, or use a brute
> force approach (as a part of -fanalyzer).  But I doubt if these simple cases are
> really useful.

Thank you for your reply.
Yes, it would be useful to see more warnings output.

I see this situation every few weeks in code bases upon manual review. The simple case is where it is boolean as above, and is just values, and the else if() the inverse.

The compiler actually generated assembler that returns '1', so it did strip out the unused branches.

As two side questions:
-- Is there anyway to see which branches are removed?
-- Is there anyway to force the compile to keep all branches? (even those it believes will never be executed).

Cheers, Jonny

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: gcc warn unreached else {}
       [not found]     ` <e20bf113efcb7fe3e533ac694aa4bd62519b3654.camel@mengyan1223.wang>
@ 2020-07-09 15:46       ` Xi Ruoyao
  2020-07-09 15:46       ` Xi Ruoyao
       [not found]       ` <6d61e32f-3d69-9ac9-0a7e-88daa154c578@jguk.org>
  2 siblings, 0 replies; 9+ messages in thread
From: Xi Ruoyao @ 2020-07-09 15:46 UTC (permalink / raw)
  To: Jonny Grant; +Cc: gcc-help

Sorry.  Forgot to CC the list.

On 2020-07-09 23:44 +0800, Xi Ruoyao wrote:
> On 2020-07-09 16:15 +0100, Jonny Grant wrote:
> > On 09/07/2020 16:00, Xi Ruoyao wrote:
> > > On 2020-07-09 10:45 +0100, Jonny Grant wrote:
> > > > Hello!
> > > > 
> > > > There is an example below, (my code is not like this example below). I'm
> > > > reporting a possible issue, and asking if there is a way to detect it in
> > > > code
> > > > bases. If it's a real issue I can file a bug report on Bugzilla.
> > > > 
> > > > Can gcc warn where code will not get to the 'return 3;' below?
> > > > 
> > > > Cheers, Jonny
> > > > 
> > > > 
> > > > int main(void)
> > > > {
> > > >     const int i = 1;
> > > >     if(1 == i)
> > > >     {
> > > >         return 1;
> > > >     }
> > > >     else if(1 != i)
> > > >     {
> > > >         return 2;
> > > >     }
> > > >     else
> > > >     {
> > > >         return 3;
> > > >     }
> > > > }
> > > 
> > > Generally finding all the branches in a program impossible to be executed
> > > is
> > > unsolvable.  Even in a program without any loop it's still NP-hard.
> > > 
> > > For some "simple" cases maybe we can implement some heuristics, or use a
> > > brute
> > > force approach (as a part of -fanalyzer).  But I doubt if these simple
> > > cases
> > > are
> > > really useful.
> > 
> > Thank you for your reply.
> > Yes, it would be useful to see more warnings output.
> > 
> > I see this situation every few weeks in code bases upon manual review. The
> > simple case is where it is boolean as above, and is just values, and the
> > else
> > if() the inverse.
> > The compiler actually generated assembler that returns '1', so it did strip
> > out the unused branches.
> > 
> > As two side questions:
> > -- Is there anyway to see which branches are removed?
> 
> You can use -fdump-rtl-expand.  For the example in OP it says:
> 
> > try_optimize_cfg iteration 1
> > 
> > Merging block 3 into block 2...
> > Merged blocks 2 and 3.
> > Merged 2 and 3 without moving.
> > Removing jump 6.
> > Merging block 4 into block 2...
> > Merged blocks 2 and 4.
> > Merged 2 and 4 without moving.
> 
> It's really not human-readable, but it's just how the optimizer works.  It
> works
> on an already-abstract representation of the code which is quite different
> from
> the "original" human-readable C code.
> 
> Another issue is, in any "serious" software projects if we output all dead-
> code
> elimination as warnings, the false warnings will spam your terminal.
> 
> Chris Lattner discussed this issues in his [article][1].  Though he was
> talking
> about undefined behaviors, the rationale is exactly same for any dead code.
> 
> [1]: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_21.html
> 
> > -- Is there anyway to force the compile to keep all branches? (even those it
> > believes will never be executed).
> 
> -O0.
-- 
Xi Ruoyao <xry111@mengyan1223.wang>
School of Aerospace Science and Technology, Xidian University


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: gcc warn unreached else {}
       [not found]     ` <e20bf113efcb7fe3e533ac694aa4bd62519b3654.camel@mengyan1223.wang>
  2020-07-09 15:46       ` Xi Ruoyao
@ 2020-07-09 15:46       ` Xi Ruoyao
       [not found]       ` <6d61e32f-3d69-9ac9-0a7e-88daa154c578@jguk.org>
  2 siblings, 0 replies; 9+ messages in thread
From: Xi Ruoyao @ 2020-07-09 15:46 UTC (permalink / raw)
  To: Jonny Grant; +Cc: gcc-help

Sorry.  Forgot to CC the list.

On 2020-07-09 23:44 +0800, Xi Ruoyao wrote:
> On 2020-07-09 16:15 +0100, Jonny Grant wrote:
> > On 09/07/2020 16:00, Xi Ruoyao wrote:
> > > On 2020-07-09 10:45 +0100, Jonny Grant wrote:
> > > > Hello!
> > > > 
> > > > There is an example below, (my code is not like this example below). I'm
> > > > reporting a possible issue, and asking if there is a way to detect it in
> > > > code
> > > > bases. If it's a real issue I can file a bug report on Bugzilla.
> > > > 
> > > > Can gcc warn where code will not get to the 'return 3;' below?
> > > > 
> > > > Cheers, Jonny
> > > > 
> > > > 
> > > > int main(void)
> > > > {
> > > >     const int i = 1;
> > > >     if(1 == i)
> > > >     {
> > > >         return 1;
> > > >     }
> > > >     else if(1 != i)
> > > >     {
> > > >         return 2;
> > > >     }
> > > >     else
> > > >     {
> > > >         return 3;
> > > >     }
> > > > }
> > > 
> > > Generally finding all the branches in a program impossible to be executed
> > > is
> > > unsolvable.  Even in a program without any loop it's still NP-hard.
> > > 
> > > For some "simple" cases maybe we can implement some heuristics, or use a
> > > brute
> > > force approach (as a part of -fanalyzer).  But I doubt if these simple
> > > cases
> > > are
> > > really useful.
> > 
> > Thank you for your reply.
> > Yes, it would be useful to see more warnings output.
> > 
> > I see this situation every few weeks in code bases upon manual review. The
> > simple case is where it is boolean as above, and is just values, and the
> > else
> > if() the inverse.
> > The compiler actually generated assembler that returns '1', so it did strip
> > out the unused branches.
> > 
> > As two side questions:
> > -- Is there anyway to see which branches are removed?
> 
> You can use -fdump-rtl-expand.  For the example in OP it says:
> 
> > try_optimize_cfg iteration 1
> > 
> > Merging block 3 into block 2...
> > Merged blocks 2 and 3.
> > Merged 2 and 3 without moving.
> > Removing jump 6.
> > Merging block 4 into block 2...
> > Merged blocks 2 and 4.
> > Merged 2 and 4 without moving.
> 
> It's really not human-readable, but it's just how the optimizer works.  It
> works
> on an already-abstract representation of the code which is quite different
> from
> the "original" human-readable C code.
> 
> Another issue is, in any "serious" software projects if we output all dead-
> code
> elimination as warnings, the false warnings will spam your terminal.
> 
> Chris Lattner discussed this issues in his [article][1].  Though he was
> talking
> about undefined behaviors, the rationale is exactly same for any dead code.
> 
> [1]: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_21.html
> 
> > -- Is there anyway to force the compile to keep all branches? (even those it
> > believes will never be executed).
> 
> -O0.
-- 
Xi Ruoyao <xry111@mengyan1223.wang>
School of Aerospace Science and Technology, Xidian University


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: gcc warn unreached else {}
  2020-07-09  9:45 gcc warn unreached else {} Jonny Grant
  2020-07-09 15:00 ` Xi Ruoyao
@ 2020-07-09 16:15 ` Martin Sebor
  2020-07-16  0:20   ` Jonny Grant
  1 sibling, 1 reply; 9+ messages in thread
From: Martin Sebor @ 2020-07-09 16:15 UTC (permalink / raw)
  To: Jonny Grant, gcc-help

On 7/9/20 3:45 AM, Jonny Grant wrote:
> Hello!
> 
> There is an example below, (my code is not like this example below). I'm reporting a possible issue, and asking if there is a way to detect it in code bases. If it's a real issue I can file a bug report on Bugzilla.
> 
> Can gcc warn where code will not get to the 'return 3;' below?

-Wduplicated-branches detects a related problem.  It's implemented
entirely in the front end and quite simplistic.  It just looks at
the chain of expressions controlling the if statements and compares
them for equality.  I think it could be enhanced with not too much
effort to detect a subset of this problem as well by considering
the operator as well as its operands.

Here's the function that does the checking and issues the warning:
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/c-family/c-warn.c#l2491

Martin

> 
> Cheers, Jonny
> 
> 
> int main(void)
> {
>      const int i = 1;
>      if(1 == i)
>      {
>          return 1;
>      }
>      else if(1 != i)
>      {
>          return 2;
>      }
>      else
>      {
>          return 3;
>      }
> }
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: gcc warn unreached else {}
       [not found]       ` <6d61e32f-3d69-9ac9-0a7e-88daa154c578@jguk.org>
@ 2020-07-10  8:20         ` Xi Ruoyao
  2020-07-10 21:50           ` Jonny Grant
  0 siblings, 1 reply; 9+ messages in thread
From: Xi Ruoyao @ 2020-07-10  8:20 UTC (permalink / raw)
  To: Jonny Grant; +Cc: gcc-help

On 2020-07-09 17:11 +0100, Jonny Grant wrote:
> Due to the const' on the 'int i = 1;' gcc removes all the other branches
> unfortunately.
> (I'd rather not use any special build macro to remove the 'const' just to see
> all the generated redundant assembler.)
> 
> main:
>         push    rbp
>         mov     rbp, rsp
>         mov     DWORD PTR [rbp-4], 1
>         mov     eax, 1
>         pop     rbp
>         ret

Use -O0.

It's nothing to do with that `const`.  With something like -O2 it would be
optimized away even if there is no `const`.  `i` is a local variable and the
compiler can determine that nobody can modify it.
-- 
Xi Ruoyao <xry111@mengyan1223.wang>
School of Aerospace Science and Technology, Xidian University


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: gcc warn unreached else {}
  2020-07-10  8:20         ` Xi Ruoyao
@ 2020-07-10 21:50           ` Jonny Grant
  0 siblings, 0 replies; 9+ messages in thread
From: Jonny Grant @ 2020-07-10 21:50 UTC (permalink / raw)
  To: Xi Ruoyao; +Cc: gcc-help



On 10/07/2020 09:20, Xi Ruoyao wrote:
> On 2020-07-09 17:11 +0100, Jonny Grant wrote:
>> Due to the const' on the 'int i = 1;' gcc removes all the other branches
>> unfortunately.
>> (I'd rather not use any special build macro to remove the 'const' just to see
>> all the generated redundant assembler.)
>>
>> main:
>>         push    rbp
>>         mov     rbp, rsp
>>         mov     DWORD PTR [rbp-4], 1
>>         mov     eax, 1
>>         pop     rbp
>>         ret
> 
> Use -O0.
> 
> It's nothing to do with that `const`.  With something like -O2 it would be
> optimized away even if there is no `const`.  `i` is a local variable and the
> compiler can determine that nobody can modify it.

Hello

Today's trunk on godbolt.org, shows same optimised out with -O0

#1 with x86-64 gcc (trunk)
g++ (Compiler-Explorer-Build) 11.0.0 20200709 (experimental)

main:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], 1
        mov     eax, 1
        pop     rbp
        ret


Maybe I am misunderstanding. Is there a way to keep all redundant assembler in gcc latest version trunk?

Thank you
Jonny


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: gcc warn unreached else {}
  2020-07-09 16:15 ` Martin Sebor
@ 2020-07-16  0:20   ` Jonny Grant
  0 siblings, 0 replies; 9+ messages in thread
From: Jonny Grant @ 2020-07-16  0:20 UTC (permalink / raw)
  To: Martin Sebor, gcc-help



On 09/07/2020 17:15, Martin Sebor wrote:
> On 7/9/20 3:45 AM, Jonny Grant wrote:
>> Hello!
>>
>> There is an example below, (my code is not like this example below). I'm reporting a possible issue, and asking if there is a way to detect it in code bases. If it's a real issue I can file a bug report on Bugzilla.
>>
>> Can gcc warn where code will not get to the 'return 3;' below?
> 
> -Wduplicated-branches detects a related problem.  It's implemented
> entirely in the front end and quite simplistic.  It just looks at
> the chain of expressions controlling the if statements and compares
> them for equality.  I think it could be enhanced with not too much
> effort to detect a subset of this problem as well by considering
> the operator as well as its operands.
> 
> Here's the function that does the checking and issues the warning:
> https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/c-family/c-warn.c#l2491
> 
> Martin
> 
>>
>> Cheers, Jonny
>>
>>
>> int main(void)
>> {
>>      const int i = 1;
>>      if(1 == i)
>>      {
>>          return 1;
>>      }
>>      else if(1 != i)
>>      {
>>          return 2;
>>      }
>>      else
>>      {
>>          return 3;
>>      }
>> }
>>
> 

I've added a ticket

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96214

Cheers
Jonny

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-07-16  0:20 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-09  9:45 gcc warn unreached else {} Jonny Grant
2020-07-09 15:00 ` Xi Ruoyao
2020-07-09 15:15   ` Jonny Grant
     [not found]     ` <e20bf113efcb7fe3e533ac694aa4bd62519b3654.camel@mengyan1223.wang>
2020-07-09 15:46       ` Xi Ruoyao
2020-07-09 15:46       ` Xi Ruoyao
     [not found]       ` <6d61e32f-3d69-9ac9-0a7e-88daa154c578@jguk.org>
2020-07-10  8:20         ` Xi Ruoyao
2020-07-10 21:50           ` Jonny Grant
2020-07-09 16:15 ` Martin Sebor
2020-07-16  0:20   ` Jonny Grant

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).