c: Implement new -Wenum-int-mismatch warning [PR105131]
commit7da9a089608b0ca09683332ce014fb6184842724
authorMarek Polacek <polacek@redhat.com>
Fri, 1 Apr 2022 20:55:58 +0000 (1 16:55 -0400)
committerMarek Polacek <polacek@redhat.com>
Wed, 18 May 2022 21:43:56 +0000 (18 17:43 -0400)
treea66671c0a6edc1a4191f4ec0d97d6a5c55ff6191
parent1875214cd1ca3e8bd0121f703537eb98edd84027
c: Implement new -Wenum-int-mismatch warning [PR105131]

In C, an enumerated type is compatible with char, a signed integer type,
or an unsigned integer type (6.7.2.2/5).  Therefore this code compiles:

  enum E { l = -1, z = 0, g = 1 };
  int foo(void);
  enum E foo(void) { return z; }

if the underlying type of 'enum E' is 'int' (if not, we emit an error).
This is different for typedefs, where C11 permits typedefs to be
redeclared to the same type, but not to compatible types.  In C++, the
code above is invalid.

It seems desirable to emit a warning in the C case, because it is
probably a mistake and definitely a portability error, given that the
choice of the underlying type is implementation-defined.

To that end, this patch implements a new -Wenum-int-mismatch warning.
Conveniently, we already have comptypes_check_enum_int to detect such
mismatches.  This warning is enabled by either -Wall or -Wc++-compat.

PR c/105131

gcc/c-family/ChangeLog:

* c.opt (Wenum-int-mismatch): New.

gcc/c/ChangeLog:

* c-decl.cc (diagnose_mismatched_decls): Warn about enum/integer type
mismatches.
* c-tree.h (comptypes_check_enum_int): Declare.
* c-typeck.cc (comptypes): No longer static.

gcc/ChangeLog:

* doc/invoke.texi: Document -Wenum-int-mismatch.

gcc/testsuite/ChangeLog:

* gcc.dg/Wenum-int-mismatch-1.c: New test.
* gcc.dg/Wenum-int-mismatch-2.c: New test.
* gcc.dg/Wenum-int-mismatch-3.c: New test.
* gcc.dg/Wenum-int-mismatch-4.c: New test.
* gcc.dg/Wenum-int-mismatch-5.c: New test.
gcc/c-family/c.opt
gcc/c/c-decl.cc
gcc/c/c-tree.h
gcc/c/c-typeck.cc
gcc/doc/invoke.texi
gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wenum-int-mismatch-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wenum-int-mismatch-5.c [new file with mode: 0644]