Bug 37281 - bad code generation with enum and -m32
Summary: bad code generation with enum and -m32
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.3.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-08-29 16:29 UTC by Guillaume Morin
Modified: 2010-05-04 04:48 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Guillaume Morin 2008-08-29 16:29:13 UTC
This is a copy of a Debian report that I made (I thought I might as well report it directly here too): http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=496965

g++ generates bad code for this program on an amd64 machine.  It works with fine in 64-bit and with older versions of gcc.  

#include <stdlib.h>
struct MyTypes {
    enum Type {
        NOVALUE = 1,
        VALUE   = 30,
        VALUE2 = 31,
        VALUE3 = -3
    };

    static bool isValue(MyTypes::Type value);
};

bool MyTypes::isValue(MyTypes::Type value)
{
    switch (value) {
      case MyTypes::VALUE:
      case MyTypes::VALUE2:
      case MyTypes::VALUE3: {
        return true;
      }
      default: {
        return false;
      }
    }
}

int main(int argc, char *argv[])
{
    if (true == MyTypes::isValue(MyTypes::Type(32))) {
        abort();
    }
    return 0;
}

guillaum@canard:~$ g++ -m32 -Wall -o e enumtest.cpp
guillaum@canard:~$ ./e
Aborted
guillaum@canard:~$ g++ -Wall -o e enumtest.cpp
guillaum@canard:~$ ./e
guillaum@canard:~$ g++-4.2 -m32 -Wall -o e enumtest.cpp
guillaum@canard:~$ ./e
guillaum@canard:~$ g++-4.1 -m32 -Wall -o e enumtest.cpp
guillaum@canard:~$ ./e

It works with -O2 though (not -O1):
guillaum@canard:~$ g++ -O2 -m32 -Wall -o e enumtest.cpp
guillaum@canard:~$ ./e


-- System Information:
Debian Release: lenny/sid
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable')
Architecture: amd64 (x86_64)
Comment 1 pinskia@gmail.com 2008-08-29 16:39:46 UTC
Subject: Re:   New: bad code generation with enum and -m32

This code is undefined as the value of  32 is outside the range of the  
enum.

Sent from my iPhone

On Aug 29, 2008, at 9:29, "gmorin1 at bloomberg dot net" <gcc-bugzilla@gcc.gnu.org 
 > wrote:

> This is a copy of a Debian report that I made (I thought I might as  
> well report
> it directly here too): http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=496965
>
> g++ generates bad code for this program on an amd64 machine.  It  
> works with
> fine in 64-bit and with older versions of gcc.
>
> #include <stdlib.h>
> struct MyTypes {
>    enum Type {
>        NOVALUE = 1,
>        VALUE   = 30,
>        VALUE2 = 31,
>        VALUE3 = -3
>    };
>
>    static bool isValue(MyTypes::Type value);
> };
>
> bool MyTypes::isValue(MyTypes::Type value)
> {
>    switch (value) {
>      case MyTypes::VALUE:
>      case MyTypes::VALUE2:
>      case MyTypes::VALUE3: {
>        return true;
>      }
>      default: {
>        return false;
>      }
>    }
> }
>
> int main(int argc, char *argv[])
> {
>    if (true == MyTypes::isValue(MyTypes::Type(32))) {
>        abort();
>    }
>    return 0;
> }
>
> guillaum@canard:~$ g++ -m32 -Wall -o e enumtest.cpp
> guillaum@canard:~$ ./e
> Aborted
> guillaum@canard:~$ g++ -Wall -o e enumtest.cpp
> guillaum@canard:~$ ./e
> guillaum@canard:~$ g++-4.2 -m32 -Wall -o e enumtest.cpp
> guillaum@canard:~$ ./e
> guillaum@canard:~$ g++-4.1 -m32 -Wall -o e enumtest.cpp
> guillaum@canard:~$ ./e
>
> It works with -O2 though (not -O1):
> guillaum@canard:~$ g++ -O2 -m32 -Wall -o e enumtest.cpp
> guillaum@canard:~$ ./e
>
>
> -- System Information:
> Debian Release: lenny/sid
>  APT prefers testing
>  APT policy: (990, 'testing'), (500, 'unstable')
> Architecture: amd64 (x86_64)
>
>
> -- 
>           Summary: bad code generation with enum and -m32
>           Product: gcc
>           Version: 4.3.1
>            Status: UNCONFIRMED
>          Severity: normal
>          Priority: P3
>         Component: c++
>        AssignedTo: unassigned at gcc dot gnu dot org
>        ReportedBy: gmorin1 at bloomberg dot net
>
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37281
>
Comment 2 Guillaume Morin 2008-08-29 16:57:42 UTC
I thought it was correct because it seems that the standard allows to cast explicity inside the range.  The range is not the one of the integral type but the one of smallest bit field that can stop all the values.  So you're completely correct.  Sorry.
Comment 3 Manuel López-Ibáñez 2008-08-29 17:00:38 UTC
In GCC 4.4 we warn about this with -Wconversion.

warning: the result of the conversion is unspecified because ‘32’ is outside the range of type ‘MyTypes::Type’
Comment 4 Jason Merrill 2010-05-04 04:48:53 UTC
In G++ 4.6 the surprising optimization will only be performed with -fstrict-enums.