This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]