[Bug c/59933] for loop goes wild with assert() enabled

2014-02-19 Thread mpolacek at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59933

Marek Polacek mpolacek at gcc dot gnu.org changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 CC||mpolacek at gcc dot gnu.org
 Resolution|--- |INVALID

--- Comment #4 from Marek Polacek mpolacek at gcc dot gnu.org ---
There's no good reproducer, but if -fno-aggressive-loop-optimizations helps,
most likely the code invokes undefined behavior.  Tentatively closing as
invalid (PR59982 was closed too).


[Bug c/59933] for loop goes wild with assert() enabled

2014-02-19 Thread warnerme at ptd dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59933

--- Comment #5 from Mark Warner warnerme at ptd dot net ---
sizeof(NSQ_del_dec_struct) / sizeof(opus_int32) is guaranteed to produced a
even number with a remainder of 0.
Note the __attribute__ ((__aligned__ (8))) to make it a multiple of 8 in size.


[Bug c/59933] for loop goes wild with assert() enabled

2014-02-19 Thread warnerme at ptd dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59933

--- Comment #6 from Mark Warner warnerme at ptd dot net ---
If it is invalid, why does -Wall not trigger anything ?


[Bug c/59933] for loop goes wild with assert() enabled

2014-02-19 Thread mpolacek at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59933

--- Comment #7 from Marek Polacek mpolacek at gcc dot gnu.org ---
(int)(sizeof(NSQ_del_dec_struct) / sizeof(opus_int32) seems to be 1168/4 = 292,
but sLPC_Q14 has only 112 elements.


[Bug c/59933] for loop goes wild with assert() enabled

2014-02-19 Thread jakub at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59933

Jakub Jelinek jakub at gcc dot gnu.org changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #8 from Jakub Jelinek jakub at gcc dot gnu.org ---
The code is not invalid C, just triggers undefined behavior, so it is not
invalid at compile time, just at runtime if you ever hit this.
GCC optimizes based on the assumption that undefined behavior doesn't happen in
a correct program.
While we have -Waggressive-loop-optimizations warning, it (intentionally) warns
solely about the case where the loop has single exit and constant loop
iteration count, which is not the case here, the number of iterations is
i = 292 ? 0 : 292 - i.
The loop will trigger undefined behavior whenever i is  292, if it is bigger,
then there is no bug.


[Bug c/59933] for loop goes wild with assert() enabled

2014-02-19 Thread ian at g0tcd dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59933

--- Comment #9 from Ian Hamilton ian at g0tcd dot com ---
Yes, that's all proper and correct. The invalid C code induces undefined
behaviour. I don't think anyone is disputing that.

However, to be pragmatic for a moment, the experience of thousands of
developers out there, working with legacy code, and trying to update their
toolset to include gcc 4.8 is that code which compiled without warnings and
worked with the old gcc compiler now still compiles without warnings, but fails
at runtime with the 4.8 series compiler.

Sometimes, the runtime failures are occasional and difficult to track down if
(for example) it lies on an error handling path. This makes it even harder for
these developers to figure out what's going on.

If the compiler could provide a warning when it encounters this sort of invalid
code, that would be a good thing, as it would highlight the old latent bugs and
give developers the opportunity to fix them.

However, it doesn't, so the developers working on legacy code really have no
alternative to either using the -fno-aggressive-loop-optimizations switch to
stabilse their legacy code (even assuming they understand what's happening), or
sticking with the old version of the compiler.

So I think the request to the gcc developers is to find a way of providing a
compiler warning when the loop optimiser encounters problem code, to give
developers a fighting chance of debugging their legacy code.


[Bug c/59933] for loop goes wild with assert() enabled

2014-02-19 Thread jakub at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59933

--- Comment #10 from Jakub Jelinek jakub at gcc dot gnu.org ---
We have -fsanitize=undefined which can catch some issues, though the array
bounds instrumentation (nor __builtin_object_size based instrumentation) has
not been added yet for GCC 4.9, will be hopefully there in the next release.
As for warnings, even the current -Waggressive-loop-optimizationsh warning (for
the const number of iterations, single loop exit easy case where you know that
if the loop is reachable, if there is undefined behavior in some loop
iteration, you will trigger it) still has occassional false positives (various
PRs about that, usually the issue is that while it is true there is such a
loop, the loop is actually dead), further warnings would have huge false
positive rate, to the extent that it would be rarely useful.


[Bug c/59933] for loop goes wild with assert() enabled

2014-02-19 Thread warnerme at ptd dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59933

--- Comment #11 from Mark Warner warnerme at ptd dot net ---
I'm confused .. what about..
for (k = i; k  (int)(sizeof(NSQ_del_dec_struct) / sizeof(opus_int32)); ++k)
... is illegal or invalid ?
Why does it only fail if -DDEBUG is defined ?
I mean, this code worked fine for months .. and now


[Bug c/59933] for loop goes wild with assert() enabled

2014-02-19 Thread jakub at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59933

--- Comment #12 from Jakub Jelinek jakub at gcc dot gnu.org ---
(In reply to Mark Warner from comment #11)
 I'm confused .. what about..
 for (k = i; k  (int)(sizeof(NSQ_del_dec_struct) / sizeof(opus_int32)); ++k)
 ... is illegal or invalid ?
 Why does it only fail if -DDEBUG is defined ?
 I mean, this code worked fine for months .. and now

The undefined behavior is if i is smaller than 292, you access out of bound
array members (well, in C already the address arithmetics is undefined behavior
when you go further than one past the last element of the array).
The sLPC_Q14 has only 112 entries, so say if i is 0, then when k is 112, you
invoke undefined behavior, because you can't read or write sLPC_Q14[112].


[Bug c/59933] for loop goes wild with assert() enabled

2014-02-19 Thread ian at g0tcd dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59933

--- Comment #13 from Ian Hamilton ian at g0tcd dot com ---
(In reply to Mark Warner from comment #11)
 I'm confused .. what about..
 for (k = i; k  (int)(sizeof(NSQ_del_dec_struct) / sizeof(opus_int32)); ++k)
 ... is illegal or invalid ?
 Why does it only fail if -DDEBUG is defined ?
 I mean, this code worked fine for months .. and now

What this code seems to be doing is copying a section at the end of the
sLPC_Q14 array at the beginning of the NSQ_del_dec_struct structure, plus all
the other structure members that follow the array (RandState[32], Q_Q10[32],
etc.).

It is doing this by deliberately running the sLPC_Q14 array index beyond the
end of the array, i.e. it is RELYING on undefined behaviour.

I'd have said your work-around solution is actually the better code.


[Bug c/59933] for loop goes wild with assert() enabled

2014-01-29 Thread ian at g0tcd dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59933

Ian Hamilton ian at g0tcd dot com changed:

   What|Removed |Added

 CC||ian at g0tcd dot com

--- Comment #2 from Ian Hamilton ian at g0tcd dot com ---
I found a similar bug in 4.8.1.

See bug report http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59982

You could try adding the -fno-aggressive-loop-optimizations flag and see if
that fixes your problem with assert() enabled.


[Bug c/59933] for loop goes wild with assert() enabled

2014-01-29 Thread ian at g0tcd dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59933

--- Comment #3 from Ian Hamilton ian at g0tcd dot com ---
Just a thought.

Does ((int)(sizeof(NSQ_del_dec_struct) / sizeof(opus_int32)) correctly give you
the size of the sLPC_Q14 array?

From playing with my test case, it seems that if the optimiser spots that k
will go beyond the end of your array, it doesn't bother checking it each time
round the loop, hence an infinte loop.

Seems that gcc 4.8's aggressive loop optimiser also gives up aggressively when
presented with invalid code.


[Bug c/59933] for loop goes wild with assert() enabled

2014-01-24 Thread warnerme at ptd dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59933

--- Comment #1 from Mark Warner warnerme at ptd dot net ---
Created attachment 31945
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=31945action=edit
C source of subroutines which contain problem for loop

This is a file from OPUS.  As sent it can't be run, but the problem was bad
enough that I thought looking at the generated code might be enough.
All, except system, include files are inlined.