Bug 42577 - [4.4 Regression] array bounds false positive with -O3, goes away with -O2
Summary: [4.4 Regression] array bounds false positive with -O3, goes away with -O2
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.4.1
: P2 normal
Target Milestone: 4.4.6
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2010-01-01 21:00 UTC by Matt Hargett
Modified: 2010-10-18 22:41 UTC (History)
1 user (show)

See Also:
Host: x86_64-linux-unknown
Target: x86_64-linux-unknown
Build: x86_64-linux-unknown
Known to work: 4.5.0
Known to fail:
Last reconfirmed: 2010-01-02 14:57:22


Attachments
pre-processed output of the file that emitted the warning (61.52 KB, text/plain)
2010-01-01 21:02 UTC, Matt Hargett
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Matt Hargett 2010-01-01 21:00:55 UTC
when building ScummVM (http://scummvm.org) using GCC 4.4.1 on Ubuntu 9.10/amd64:
matt@ghuang-desktop:~/src/scummvm$ g++-4.4 -Wp,-MMD,"engines/saga/.deps/animation.d",-MQ,"engines/saga/animation.o",-MP -Wall -Werror -g -ansi -W -Wno-unused-parameter -Wno-empty-body -pedantic -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder -fno-strict-aliasing  -Wpointer-arith -Wcast-qual -Wcast-align -Wshadow -Wimplicit -Wnon-virtual-dtor -Wwrite-strings -fno-rtti -fno-exceptions -fcheck-new -O3 -Wuninitialized -DSCUMMVM_SVN_REVISION=\"46563\" -DHAVE_CONFIG_H -DUNIX -DDATA_PATH=\"/usr/local/share/scummvm\" -DPLUGIN_DIRECTORY=\"/usr/local/lib/scummvm\" -DSDL_BACKEND -DENABLE_SCUMM=STATIC_PLUGIN -DENABLE_SCUMM_7_8 -DENABLE_HE -DENABLE_AGI=STATIC_PLUGIN -DENABLE_AGOS=STATIC_PLUGIN -DENABLE_AGOS2 -DENABLE_CINE=STATIC_PLUGIN -DENABLE_CRUISE=STATIC_PLUGIN -DENABLE_DRACI=STATIC_PLUGIN -DENABLE_DRASCULA=STATIC_PLUGIN -DENABLE_GOB=STATIC_PLUGIN -DENABLE_GROOVIE=STATIC_PLUGIN -DENABLE_GROOVIE2 -DENABLE_KYRA=STATIC_PLUGIN -DENABLE_LOL -DENABLE_LURE=STATIC_PLUGIN -DENABLE_M4=STATIC_PLUGIN -DENABLE_MADE=STATIC_PLUGIN -DENABLE_PARALLACTION=STATIC_PLUGIN -DENABLE_QUEEN=STATIC_PLUGIN -DENABLE_SAGA=STATIC_PLUGIN -DENABLE_IHNM -DENABLE_SAGA2 -DENABLE_SCI=STATIC_PLUGIN -DENABLE_SCI32 -DENABLE_SKY=STATIC_PLUGIN -DENABLE_SWORD1=STATIC_PLUGIN -DENABLE_SWORD2=STATIC_PLUGIN -DENABLE_TEENAGENT=STATIC_PLUGIN -DENABLE_TINSEL=STATIC_PLUGIN -DENABLE_TOUCHE=STATIC_PLUGIN -DENABLE_TUCKER=STATIC_PLUGIN -I. -I. -I./engines -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -c engines/saga/animation.cpp
cc1plus: warnings being treated as errors
./engines/saga/animation.h: In member function ‘int Saga::Anim::playCutaway(int, bool)’:
./engines/saga/animation.h:175: error: array subscript is above array bounds

Relevant code in question:
#define MAX_ANIMATIONS 10
AnimationData *_animations[MAX_ANIMATIONS];

void validateAnimationId(uint16 animId) {
  if (animId >= MAX_ANIMATIONS) {
    // ...
  } else {
    if (_animations[animId] == NULL) {
      error("validateAnimationId: animId=%i unassigned.", animId);
    }
  }
}

pre-processed output is attached. This bug appears to already be fixed in GCC 4.5 snapshot as on 2009-12-28.
Comment 1 Matt Hargett 2010-01-01 21:02:30 UTC
Created attachment 19439 [details]
pre-processed output of the file that emitted the warning

commandline:
g++-4.4 -Wp,-MMD,"engines/saga/.deps/animation.d",-MQ,"engines/saga/animation.o",-MP -Wall -Werror -g -ansi -W -Wno-unused-parameter -Wno-empty-body -pedantic -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder -fno-strict-aliasing  -Wpointer-arith -Wcast-qual -Wcast-align -Wshadow -Wimplicit -Wnon-virtual-dtor -Wwrite-strings -fno-rtti -fno-exceptions -fcheck-new -O3 -Wuninitialized -DSCUMMVM_SVN_REVISION=\"46563\" -DHAVE_CONFIG_H -DUNIX -DDATA_PATH=\"/usr/local/share/scummvm\" -DPLUGIN_DIRECTORY=\"/usr/local/lib/scummvm\" -DSDL_BACKEND -DENABLE_SCUMM=STATIC_PLUGIN -DENABLE_SCUMM_7_8 -DENABLE_HE -DENABLE_AGI=STATIC_PLUGIN -DENABLE_AGOS=STATIC_PLUGIN -DENABLE_AGOS2 -DENABLE_CINE=STATIC_PLUGIN -DENABLE_CRUISE=STATIC_PLUGIN -DENABLE_DRACI=STATIC_PLUGIN -DENABLE_DRASCULA=STATIC_PLUGIN -DENABLE_GOB=STATIC_PLUGIN -DENABLE_GROOVIE=STATIC_PLUGIN -DENABLE_GROOVIE2 -DENABLE_KYRA=STATIC_PLUGIN -DENABLE_LOL -DENABLE_LURE=STATIC_PLUGIN -DENABLE_M4=STATIC_PLUGIN -DENABLE_MADE=STATIC_PLUGIN -DENABLE_PARALLACTION=STATIC_PLUGIN -DENABLE_QUEEN=STATIC_PLUGIN -DENABLE_SAGA=STATIC_PLUGIN -DENABLE_IHNM -DENABLE_SAGA2 -DENABLE_SCI=STATIC_PLUGIN -DENABLE_SCI32 -DENABLE_SKY=STATIC_PLUGIN -DENABLE_SWORD1=STATIC_PLUGIN -DENABLE_SWORD2=STATIC_PLUGIN -DENABLE_TEENAGENT=STATIC_PLUGIN -DENABLE_TINSEL=STATIC_PLUGIN -DENABLE_TOUCHE=STATIC_PLUGIN -DENABLE_TUCKER=STATIC_PLUGIN -I. -I. -I./engines -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -E engines/saga/animation.cpp > ~/array-bounds-false-positive.i
Comment 2 Matt Hargett 2010-01-01 21:16:33 UTC
sorry, I lied. This is still an issue in GCC 4.5.20091228.
Comment 3 Richard Biener 2010-01-01 22:42:00 UTC
The array indexing is done with D.25175_104, but

  D.25173_102 = (uint16) cutawaySlot_256;
  D.25174_103 = D.25173_102 + 10;
  D.25175_104 = (int) D.25174_103;
...
  if (D.25174_103 > 9)
    goto <bb 26>;
  else
    goto <bb 30>;

the actual check is done on D.25174_103.  We do not add asserts for
D.25175_104 on the edge to BB30.  D.25174 is unsigned short.

So we end up with

D.25173_102: [0, 1]
D.25174_103: [10, 11]
D.25175_104: [10, 11]

and warn for the access that is dominated by BB30.

So the issue is that we warn for dead code.
Comment 4 Richard Biener 2010-01-02 14:57:22 UTC
I have a patch.
Comment 5 Richard Biener 2010-01-02 16:41:25 UTC
It's at least a regression towards where we didn't have array bound warnings.
Comment 6 Richard Biener 2010-01-02 19:15:13 UTC
Subject: Bug 42577

Author: rguenth
Date: Sat Jan  2 19:14:52 2010
New Revision: 155577

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=155577
Log:
2010-01-02  Richard Guenther  <rguenther@suse.de>

	PR middle-end/42577
	* tree-vrp.c (check_all_array_refs): Skip non-excutable blocks.
	(simplify_switch_using_ranges): Mark to be removed edges
	as non-executable.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/tree-vrp.c

Comment 7 Richard Biener 2010-01-02 19:15:29 UTC
Fixed on the trunk sofar.
Comment 8 Matt Hargett 2010-01-03 19:57:49 UTC
can this be backported to 4.4 as well so I can integrate it into our 4.4-based toolchain?
Comment 9 Richard Biener 2010-01-03 22:33:44 UTC
The patch should apply more-or-less literally to the 4.4 branch.
Comment 10 Matt Hargett 2010-01-04 01:04:30 UTC
what I mean to ask is: can this fix be committed to the 4.4 branch? I'd prefer to minimize the number of local patches we apply to our custom build.

Thanks for the quick fix, by the way! :)
Comment 11 Richard Biener 2010-01-04 14:26:32 UTC
Sure, but let's wait for possible problems with the patch to show up in 4.5.
Comment 12 Matt Hargett 2010-02-10 01:26:12 UTC
I haven't had any issues come up with this in the last month, testing with a new profiledbootstrap of GCC trunk every week or so. Can this be backported to 4.4 now? Or is there some specific testing you'd like me to do? Let me know :)

Thanks!
Comment 13 Matt Hargett 2010-10-18 22:41:01 UTC
Verified fixed in Ubuntu 10.10's gcc 4.4, 4.5, and 4.6 (gcc-snapshot) packages on amd64.