User account creation filtered due to spam.

Bug 37281

Summary: bad code generation with enum and -m32
Product: gcc Reporter: Guillaume Morin <guillaume>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED INVALID    
Severity: normal CC: gcc-bugs, jason, manu
Priority: P3    
Version: 4.3.1   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:

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.