This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/80733] New: -fstrict-enum ineffective, incorrect -Wtype-limits warning
- From: "msebor at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sat, 13 May 2017 00:19:38 +0000
- Subject: [Bug tree-optimization/80733] New: -fstrict-enum ineffective, incorrect -Wtype-limits warning
- Auto-submitted: auto-generated
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)