[Bug tree-optimization/80733] New: -fstrict-enum ineffective, incorrect -Wtype-limits warning

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sat May 13 01:33:00 GMT 2017


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80733

            Bug ID: 80733
           Summary: -fstrict-enum ineffective, incorrect -Wtype-limits
                    warning
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

The -fstrict-enums option's effect is documented as

    Allow the compiler to optimize using the assumption that a value of
enumerated type can only be one of the values of the enumeration (as defined in
the C++ standard; basically, a value that can be represented in the minimum
number of bits needed to represent all the enumerators). 

The program below shows that GCC doesn't actually perform the optimization.  It
only appears to constrain the range of values of the type to that of the
underlying type, apparently disregarding the TYPE_{MIN,MAX}_VALUE set by the
C++ front end in 
finish_enum_value_list in response to the option.

To add insult to injury, the -Wtype-limits warning suggests that GCC actually
does perform the optimization (the "not eliminated (bug), warning (bug)" case
below).

When compiled without -fstrict-enums, the emitted code stays the same.  The
only thing that changes is that the first warning (on line 16) is not issued.

$ cat t.C && gcc -O2 -S -Wall -Wextra -Wpedantic -Wconversion -xc++
-fstrict-enums -fdump-tree-optimized=/dev/stdout t.C | grep -E "(^void
(foo|bar)|abort)"
enum E { e0, e15 = 15 };
enum __attribute__ ((packed)) F { f0, f15 = 15 };

void foo (E e)
{
  if (e > 15) __builtin_abort ();   // not eliminated (bug)
}

void bar (E e)
{
  if (e > 255) __builtin_abort ();   // not eliminated (bug)
}

void foo (F f)
{
  if (f > 15) __builtin_abort ();   // not eliminated (bug), warning (bug)
}

void bar (F f)
{
  if (f > 255) __builtin_abort ();   // eliminated, warning (good)
}
t.C: In function ‘void foo(F)’:
t.C:16:9: warning: comparison is always false due to limited range of data type
[-Wtype-limits]
   if (f > 15) __builtin_abort ();   // not eliminated (bug), warning (bug)
       ~~^~~~
t.C: In function ‘void bar(F)’:
t.C:21:9: warning: comparison is always false due to limited range of data type
[-Wtype-limits]
   if (f > 255) __builtin_abort ();   // eliminated, warning
       ~~^~~~~
void foo(E) (E e)
  __builtin_abort ();
void bar(E) (E e)
  __builtin_abort ();
void foo(F) (F f)
  __builtin_abort ();
void bar(F) (F f)


More information about the Gcc-bugs mailing list