public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/36170] New: enum variable operation behaviour and -O2
@ 2008-05-07 15:02 john dot spelis at 3dlabs dot com
2008-05-07 17:24 ` [Bug c++/36170] " pinskia at gcc dot gnu dot org
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: john dot spelis at 3dlabs dot com @ 2008-05-07 15:02 UTC (permalink / raw)
To: gcc-bugs
The following program shows a case where
the 4.3.0 C++ compiler omits a check on an ENUM
variable when compiled with -O2 but keeps it when
-O is used ?
Targets where this occurs; at least x86, arm-*-linux-*
optEnum = (Options::Id::Type) getopt_long( ... ) ;
if( optEnum == -1 ) /* This test skipped with -O2 but not -O */
break;
switch( optEnum ) {
:
}
The workaround for this "bug" is explicitly set
an enum value of -1
i.e.
enum Type {
eHelp = 'h',
::
Dummy = -1 /* fixes issue */
}
Some people say this is an interpretation of the C++ Spec
but why does the program behaviour change so radically
with/without the optimiser and without any warnings ?
This behviour is reproducible with the attached program on
an x86 build of 4.3.0
E.g.
./configure --enable-languages=c,c++ --prefix=/tmp/gcc
g++ -O -o m m.cxx
./m -> program runs and exit's
g++ -O2 -o m m.cxx
./m -> program prints -1 forever
=====
m.cxx
=====
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
typedef unsigned long uint32_t ;
typedef unsigned char uint8_t ;
#define ANSI_BOLD ""
#define ANSI_RED ""
#define ANSI_RESET ""
#define HAVE_GETOPT 1
class Background {
public:
enum Type {
eMandel = 0,
eGrid,
eFlat,
eGouraud,
};
};
class Options {
public:
Options( void ) {
memset( this, 0x00, sizeof(*this) );
bailOut = 4;
maxIteration = 240;
size[0] = 64;
size[1] = 32;
surfSize[0] = size[0];
surfSize[1] = size[1];
offset[0] = 0;
offset[1] = 0;
coordX[0] = -2;
coordX[1] = 2;
coordY[0] = -2;
coordY[1] = 2;
bRandomColours = true;
background = Background::eMandel;
#if USE_HARDWARE
bUseTCSET = true;
#endif
}
bool bAnimate;
bool bUseGUI;
bool bSetMode;
bool bListModes;
bool bDumpImage;
bool bUseTCSET;
bool bWantClears;
bool bRandomColours;
bool bFixedAspect;
bool bFullScreen;
bool bSingleBuffer;
uint32_t modeX, modeY;
uint32_t vidDevice;
uint32_t vidRotate;
uint32_t bailOut;
uint32_t maxIteration;
uint32_t loopCount;
uint32_t size[2];
uint32_t surfSize[2];
uint32_t offset[2];
float coordX[2];
float coordY[2];
Background::Type background;
bool bStall;
uint32_t benchmarkMode;
};
bool gVerbose = false;
bool gVeryVerbose = false;
bool gAbortNow = false;
bool processArgs( int argc, char *const argv[], Options &opts )
{
#if HAVE_GETOPT
class Options {
public:
class Id {
public:
enum Type {
eHelp = 'h',
eHelpL = 1,
eSize,
eCoords,
eCoordSet,
eClearFirst,
eBail,
eMaxIt,
eColourMap,
eAnimate,
eSetMode,
eLoop,
eFullScreen,
eListModes,
eOffset,
eAspect,
eDemo,
eNoSync,
eVidDevice,
eNoTCSET,
eGUI,
eDumpImage,
eBackground,
eRotate,
eVerbose,
eStall,
eBench,
#if 0 /* set to '1' as workaround */
eDummy = -1
#endif
};
};
class Args {
public:
enum Type {
eNone,
eReq,
eOpt,
};
};
const char *name;
Options::Args::Type args;
Id::Type id;
const char *help;
};
Options::Id::Type optEnum;
int optIndex;
uint32_t i;
bool bSuccess = true;
static Options options[] = {
{ "help", Options::Args::eNone, Options::Id::eHelp,
"Show this help message" },
{ "size", Options::Args::eReq, Options::Id::eSize,
"Size of rendered image" },
{ "coords", Options::Args::eReq, Options::Id::eCoords,
"Co-ordinates of rendered image" },
{ "coordSet", Options::Args::eReq, Options::Id::eCoordSet,
"Select a predefined set of co-ordinates" },
{ "clearFirst", Options::Args::eNone,
Options::Id::eClearFirst, NULL },
{ "bail", Options::Args::eReq, Options::Id::eBail,
"Bailout value" },
{ "maxIt", Options::Args::eReq, Options::Id::eMaxIt,
"Maximum iteration count" },
{ "colourMap", Options::Args::eReq, Options::Id::eColourMap,
"Set the colour style" },
{ "animate", Options::Args::eNone, Options::Id::eAnimate,
"Run in animation mode" },
{ "setMode", Options::Args::eOpt, Options::Id::eSetMode,
"Set the given video mode" },
{ "loop", Options::Args::eOpt, Options::Id::eLoop,
"Number of times to loop in animation mode" },
{ "fullScreen", Options::Args::eNone,
Options::Id::eFullScreen, "Buffer size matches video resolution even if render
size is smaller" },
{ "listModes", Options::Args::eNone, Options::Id::eListModes,
"List available video modes" },
{ "offset", Options::Args::eOpt, Options::Id::eOffset,
"Offset to render area if render size is smaller than video resolution" },
{ "aspect", Options::Args::eOpt, Options::Id::eAspect,
"Keep 1:1 aspect ratio or stretch to fill" },
{ "demo", Options::Args::eNone, Options::Id::eDemo,
"Enable demo mode (480x272 animation)" },
{ "noSync", Options::Args::eNone, Options::Id::eNoSync,
"Disable video sync by running single buffered" },
{ "vidDevice", Options::Args::eReq, Options::Id::eVidDevice,
"Use the given video device" },
{ "noTCSET", Options::Args::eNone, Options::Id::eNoTCSET,
"Do not use the TCSET ioctl" },
{ "gui", Options::Args::eNone, Options::Id::eGUI,
"Run in GUI mode" },
{ "dump", Options::Args::eNone, Options::Id::eDumpImage,
"Dump the rendered image as ascii text" },
{ "back", Options::Args::eReq,
Options::Id::eBackground, "Set the background style for animation mode" },
{ "rotate", Options::Args::eReq, Options::Id::eRotate,
"Rotate the video output by 90, 180, 270, FlipV, FlipH" },
{ "verbose", Options::Args::eNone, Options::Id::eVerbose,
"Enable debugging output" },
{ "stall", Options::Args::eNone, Options::Id::eStall,
"Stall on the first frame" },
{ "bench", Options::Args::eOpt, Options::Id::eBench,
"Benchmark mode" },
};
asm("L:");
while( 1 ) {
optEnum = (Options::Id::Type) getopt_long( argc, argv, "h",
NULL, &optIndex);
if( optEnum == -1 )
break;
switch( optEnum ) {
case Options::Id::eVerbose:
gVerbose = true;
gVeryVerbose = true;
continue;
case Options::Id::eHelp:
case Options::Id::eHelpL:
printf( "Mandelbrot options:\n" );
bSuccess = false;
continue;
case Options::Id::eBail:
opts.bailOut = atoi( optarg );
printf("Setting bail out to %d\n",
opts.bailOut);
continue;
case Options::Id::eMaxIt:
opts.maxIteration = atoi( optarg );
printf("Setting maximum iteration to %d\n",
opts.maxIteration);
continue;
case Options::Id::eColourMap:
opts.bRandomColours = atoi( optarg );
printf("Setting colour map to type #%d\n",
opts.bRandomColours);
continue;
case Options::Id::eCoordSet:
i = atoi(optarg);
switch( i ) {
case 0:
opts.coordX[0] = -2;
opts.coordX[1] = 2;
opts.coordY[0] = -2;
opts.coordY[1] = 2;
opts.bRandomColours = true;
break;
case 1:
opts.coordX[0] =
-0.55472656250f; opts.coordX[1] = 0.016328125f - 0.55472656250f;
opts.coordY[0] =
-0.50505859375f; opts.coordY[1] = 0.016328125f - 0.50505859375f;
opts.bRandomColours = false;
break;
default:
fprintf(stderr, ANSI_BOLD
ANSI_RED "Invalidate co-ordinate set request: %d!" ANSI_RESET "\n", i);
}
printf( "Coords set to (%f, %f) -> (%f, %f)\n",
opts.coordX[0], opts.coordY[0], opts.coordX[1], opts.coordY[1] );
continue;
case Options::Id::eSize:
sscanf( optarg, "%dx%d", &opts.size[0],
&opts.size[1] );
printf( "Size set to %d x %d\n", opts.size[0],
opts.size[1] );
continue;
case Options::Id::eOffset:
if( optarg ) {
sscanf( optarg, "%d,%d",
&opts.offset[0], &opts.offset[1] );
printf( "Offset set to (%d, %d)\n",
opts.offset[0], opts.offset[1] );
} else
opts.offset[0] = opts.offset[1] = ~0U;
continue;
case Options::Id::eCoords:
sscanf( optarg, "%f,%f,%f,%f", &opts.coordX[0],
&opts.coordY[0], &opts.coordX[1], &opts.coordY[1] );
printf( "Coords set to (%f, %f) -> (%f, %f)\n",
opts.coordX[0], opts.coordY[0], opts.coordX[1], opts.coordY[1] );
continue;
case Options::Id::eClearFirst:
opts.bWantClears = true;
continue;
case Options::Id::eAnimate:
opts.bAnimate = true;
continue;
case Options::Id::eGUI:
opts.bUseGUI = true;
continue;
case Options::Id::eDumpImage:
opts.bDumpImage = true;
continue;
case Options::Id::eSetMode:
opts.bSetMode = true;
if( optarg ) {
sscanf( optarg, "%dx%d", &opts.modeX,
&opts.modeY );
printf( "Mode size set to %d x %d\n",
opts.modeX, opts.modeY );
}
continue;
case Options::Id::eVidDevice:
sscanf( optarg, "%d", &opts.vidDevice );
printf( "Video device set to %d\n",
opts.vidDevice );
continue;
case Options::Id::eListModes:
opts.bListModes = true;
continue;
case Options::Id::eLoop:
if( optarg ) {
sscanf( optarg, "%d", &opts.loopCount
);
printf( "Loop count set to %d\n",
opts.loopCount );
opts.loopCount--;
} else
opts.loopCount = ~0;
continue;
case Options::Id::eFullScreen:
opts.bFullScreen = true;
continue;
case Options::Id::eAspect:
if( optarg ) {
sscanf( optarg, "%d", &i );
opts.bFixedAspect = i ? true : false;
printf( "Fixed aspect set to %d\n",
opts.bFixedAspect );
} else
opts.bFixedAspect = true;
continue;
case Options::Id::eNoSync:
opts.bSingleBuffer = true;
continue;
case Options::Id::eNoTCSET:
opts.bUseTCSET = false;
continue;
case Options::Id::eDemo:
if( gVerbose ) printf( "Running with demo options.\n" );
opts.bFixedAspect = true;
opts.bFullScreen = true;
opts.bAnimate = true;
opts.bSetMode = true;
opts.loopCount = 1;
opts.offset[0] = ~0U;
opts.offset[1] = ~0U;
opts.size[0] = 272;
opts.size[1] = 272;
continue;
case Options::Id::eBackground:
sscanf( optarg, "%d", &i );
opts.background = (Background::Type) i;
printf( "Background style set to %d\n",
opts.background );
continue;
case Options::Id::eRotate:
sscanf( optarg, "%d", &opts.vidRotate );
printf( "Video rotation set to %d\n",
opts.vidRotate );
continue;
case Options::Id::eStall:
opts.bStall = true;
continue;
case Options::Id::eBench:
if( optarg )
sscanf( optarg, "%d", &opts.benchmarkMode );
else
opts.benchmarkMode = 1;
printf( "Benchmark mode set to %d\n", opts.benchmarkMode );
continue;
default:
break;
}
fprintf(stderr, ANSI_BOLD ANSI_RED "Got unknown option id: %d!"
ANSI_RESET "\n", optEnum);
bSuccess = false;
}
return bSuccess;
#else
fprintf(stderr, ANSI_BOLD ANSI_RED "No getopt. Ignoring command line
arguments!" ANSI_RESET "\n");
return true;
#endif
}
int main( int argc, char *argv[] )
{
bool bSuccess = true;
const char *env;
class Options opts ;
if( !processArgs(argc, argv, opts) ) {
fprintf( stderr, ANSI_BOLD ANSI_RED "Failed to process command
line arguments!" ANSI_RESET "\n" );
bSuccess = false;
}
return(0) ;
}
--
Summary: enum variable operation behaviour and -O2
Product: gcc
Version: 4.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: john dot spelis at 3dlabs dot com
GCC build triplet: i686-pc-linux-gnu
GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36170
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug c++/36170] enum variable operation behaviour and -O2
2008-05-07 15:02 [Bug c++/36170] New: enum variable operation behaviour and -O2 john dot spelis at 3dlabs dot com
@ 2008-05-07 17:24 ` pinskia at gcc dot gnu dot org
2008-05-07 18:39 ` john dot spelis at 3dlabs dot com
2010-05-04 4:49 ` jason at gcc dot gnu dot org
2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2008-05-07 17:24 UTC (permalink / raw)
To: gcc-bugs
------- Comment #1 from pinskia at gcc dot gnu dot org 2008-05-07 17:23 -------
And C++ standard says if the value is out of range of the enum, the behavior is
undefined so this is not a bug.
--
pinskia at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution| |INVALID
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36170
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug c++/36170] enum variable operation behaviour and -O2
2008-05-07 15:02 [Bug c++/36170] New: enum variable operation behaviour and -O2 john dot spelis at 3dlabs dot com
2008-05-07 17:24 ` [Bug c++/36170] " pinskia at gcc dot gnu dot org
@ 2008-05-07 18:39 ` john dot spelis at 3dlabs dot com
2010-05-04 4:49 ` jason at gcc dot gnu dot org
2 siblings, 0 replies; 4+ messages in thread
From: john dot spelis at 3dlabs dot com @ 2008-05-07 18:39 UTC (permalink / raw)
To: gcc-bugs
------- Comment #2 from john dot spelis at 3dlabs dot com 2008-05-07 18:38 -------
Subject: Re: enum variable operation behaviour and -O2
Thanks for ending that issue.
Best Regards
On 7 May 2008, pinskia at gcc dot gnu dot org wrote:
>
>
> ------- Comment #1 from pinskia at gcc dot gnu dot org 2008-05-07 17:23 -------
> And C++ standard says if the value is out of range of the enum, the behavior is
> undefined so this is not a bug.
>
>
> --
>
> pinskia at gcc dot gnu dot org changed:
>
> What |Removed |Added
> ----------------------------------------------------------------------------
> Status|UNCONFIRMED |RESOLVED
> Resolution| |INVALID
>
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36170
>
> ------- You are receiving this mail because: -------
> You reported the bug, or are watching the reporter.
>
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36170
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug c++/36170] enum variable operation behaviour and -O2
2008-05-07 15:02 [Bug c++/36170] New: enum variable operation behaviour and -O2 john dot spelis at 3dlabs dot com
2008-05-07 17:24 ` [Bug c++/36170] " pinskia at gcc dot gnu dot org
2008-05-07 18:39 ` john dot spelis at 3dlabs dot com
@ 2010-05-04 4:49 ` jason at gcc dot gnu dot org
2 siblings, 0 replies; 4+ messages in thread
From: jason at gcc dot gnu dot org @ 2010-05-04 4:49 UTC (permalink / raw)
To: gcc-bugs
------- Comment #3 from jason at gcc dot gnu dot org 2010-05-04 04:49 -------
In G++ 4.6 the surprising optimization will only be performed with
-fstrict-enums.
--
jason at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jason at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36170
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-05-04 4:49 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-07 15:02 [Bug c++/36170] New: enum variable operation behaviour and -O2 john dot spelis at 3dlabs dot com
2008-05-07 17:24 ` [Bug c++/36170] " pinskia at gcc dot gnu dot org
2008-05-07 18:39 ` john dot spelis at 3dlabs dot com
2010-05-04 4:49 ` jason at gcc dot gnu dot org
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).