* [Bug c/105131] Warning for mismatched declaration/definition with enum
2022-04-01 19:56 [Bug c/105131] New: Warning for mismatched declaration/definition with enum rth at gcc dot gnu.org
2022-04-01 20:17 ` [Bug c/105131] " mpolacek at gcc dot gnu.org
@ 2022-04-01 20:59 ` mpolacek at gcc dot gnu.org
2022-05-17 20:34 ` mpolacek at gcc dot gnu.org
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2022-04-01 20:59 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105131
--- Comment #2 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Maybe something like the attached patch would work (but needs a new option,
maybe -Wenum-int-mismatch, possibly enabled by -Wall?). With it, the following
test
enum E { l = -1, z = 0, g = 1 };
int foo(void);
enum E foo(void) { return z; }
void bar(int);
void bar(enum E);
extern enum E arr[10];
extern int arr[10];
is diagnosed like this:
105131.c:3:8: warning: conflicting types for ‘foo’ due to enum/integer
mismatch; have ‘enum E(void)’
3 | enum E foo(void) { return z; }
| ^~~
105131.c:2:5: note: previous declaration of ‘foo’ with type ‘int(void)’
2 | int foo(void);
| ^~~
105131.c:6:6: warning: conflicting types for ‘bar’ due to enum/integer
mismatch; have ‘void(enum E)’
6 | void bar(enum E);
| ^~~
105131.c:5:6: note: previous declaration of ‘bar’ with type ‘void(int)’
5 | void bar(int);
| ^~~
105131.c:9:12: warning: conflicting types for ‘arr’ due to enum/integer
mismatch; have ‘int[10]’
9 | extern int arr[10];
| ^~~
105131.c:8:15: note: previous declaration of ‘arr’ with type ‘enum E[10]’
8 | extern enum E arr[10];
| ^~~
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index c701f07befe..60a0bb3ea36 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -1995,9 +1995,12 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
bool pedwarned = false;
bool warned = false;
+ bool enum_and_int_p = false;
auto_diagnostic_group d;
- if (!comptypes (oldtype, newtype))
+ int comptypes_result = comptypes_check_enum_int (oldtype, newtype,
+ &enum_and_int_p);
+ if (!comptypes_result)
{
if (TREE_CODE (olddecl) == FUNCTION_DECL
&& fndecl_built_in_p (olddecl, BUILT_IN_NORMAL)
@@ -2139,6 +2142,14 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
return false;
}
}
+ else if (enum_and_int_p && TREE_CODE (newdecl) != TYPE_DECL)
+ {
+ location_t newloc = DECL_SOURCE_LOCATION (newdecl);
+ auto_diagnostic_group d;
+ warned = warning_at (newloc, 0, "conflicting types for %q+D due to "
+ "enum/integer mismatch; have %qT", newdecl,
+ newtype);
+ }
/* Redeclaration of a type is a constraint violation (6.7.2.3p1),
but silently ignore the redeclaration if either is in a system
@@ -2148,7 +2159,6 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
if (TREE_CODE (newdecl) == TYPE_DECL)
{
bool types_different = false;
- int comptypes_result;
comptypes_result
= comptypes_check_different_types (oldtype, newtype, &types_different);
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index c70f0ba5ab6..2bcb9662620 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -685,6 +685,7 @@ extern tree require_complete_type (location_t, tree);
extern bool same_translation_unit_p (const_tree, const_tree);
extern int comptypes (tree, tree);
extern int comptypes_check_different_types (tree, tree, bool *);
+extern int comptypes_check_enum_int (tree, tree, bool *);
extern bool c_vla_type_p (const_tree);
extern bool c_mark_addressable (tree, bool = false);
extern void c_incomplete_type_error (location_t, const_tree, const_tree);
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 6c4af5e4cde..b6a45fd9836 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -1055,7 +1055,7 @@ comptypes (tree type1, tree type2)
/* Like comptypes, but if it returns non-zero because enum and int are
compatible, it sets *ENUM_AND_INT_P to true. */
-static int
+int
comptypes_check_enum_int (tree type1, tree type2, bool *enum_and_int_p)
{
const struct tagged_tu_seen_cache * tagged_tu_seen_base1 =
tagged_tu_seen_base;
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug c/105131] Warning for mismatched declaration/definition with enum
2022-04-01 19:56 [Bug c/105131] New: Warning for mismatched declaration/definition with enum rth at gcc dot gnu.org
` (2 preceding siblings ...)
2022-05-17 20:34 ` mpolacek at gcc dot gnu.org
@ 2022-05-18 23:13 ` cvs-commit at gcc dot gnu.org
2022-05-18 23:14 ` mpolacek at gcc dot gnu.org
4 siblings, 0 replies; 6+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-05-18 23:13 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105131
--- Comment #3 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:
https://gcc.gnu.org/g:7da9a089608b0ca09683332ce014fb6184842724
commit r13-627-g7da9a089608b0ca09683332ce014fb6184842724
Author: Marek Polacek <polacek@redhat.com>
Date: Fri Apr 1 16:55:58 2022 -0400
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.
^ permalink raw reply [flat|nested] 6+ messages in thread