public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c: Implement new -Wenum-int-mismatch warning [PR105131]
@ 2022-05-17 23:56 Marek Polacek
  2022-05-18 10:14 ` Pedro Alves
  0 siblings, 1 reply; 6+ messages in thread
From: Marek Polacek @ 2022-05-17 23:56 UTC (permalink / raw)
  To: GCC Patches, Joseph Myers

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.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

	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/c-family/c.opt                          |  4 +++
 gcc/c/c-decl.cc                             | 13 ++++++--
 gcc/c/c-tree.h                              |  1 +
 gcc/c/c-typeck.cc                           |  2 +-
 gcc/doc/invoke.texi                         | 20 ++++++++++++
 gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c | 35 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c | 35 +++++++++++++++++++++
 7 files changed, 107 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c
 create mode 100644 gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 035b1de0d84..0cb64283261 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -638,6 +638,10 @@ Wenum-conversion
 C ObjC C++ ObjC++ Var(warn_enum_conversion) Init(0) Warning LangEnabledBy(C ObjC,Wextra)
 Warn about implicit conversion of enum types.
 
+Wenum-int-mismatch
+C ObjC Var(warn_enum_int_mismatch) Warning LangEnabledBy(C ObjC,Wall)
+Warn about enum/integer type mismatches.
+
 Werror
 C ObjC C++ ObjC++
 ; Documented in common.opt
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 83655548fc4..5266a61b859 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -1993,9 +1993,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)
@@ -2137,6 +2140,13 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
 	  return false;
 	}
     }
+  /* Warn about enum/integer type mismatches.  They are compatible types
+     (C2X 6.7.2.2/5), but may pose portability problems.  */
+  else if (enum_and_int_p && TREE_CODE (newdecl) != TYPE_DECL)
+    warned = warning_at (DECL_SOURCE_LOCATION (newdecl),
+			 OPT_Wenum_int_mismatch,
+			 "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
@@ -2146,7 +2156,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 bcfe08b82bc..4f3611f1b89 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;
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e8e6d4e039b..60505bcd61f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -349,6 +349,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wno-div-by-zero  -Wdouble-promotion @gol
 -Wduplicated-branches  -Wduplicated-cond @gol
 -Wempty-body  -Wno-endif-labels  -Wenum-compare  -Wenum-conversion @gol
+-Wenum-int-mismatch @gol
 -Werror  -Werror=*  -Wexpansion-to-defined  -Wfatal-errors @gol
 -Wfloat-conversion  -Wfloat-equal  -Wformat  -Wformat=2 @gol
 -Wno-format-contains-nul  -Wno-format-extra-args  @gol
@@ -5759,6 +5760,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
 -Wdangling-pointer=2  @gol
 -Wduplicate-decl-specifier @r{(C and Objective-C only)} @gol
 -Wenum-compare @r{(in C/ObjC; this is on by default in C++)} @gol
+-Wenum-int-mismatch @r{(C and Objective-C only)} @gol
 -Wformat   @gol
 -Wformat-overflow  @gol
 -Wformat-truncation  @gol
@@ -8735,6 +8737,24 @@ Warn when a value of enumerated type is implicitly converted to a
 different enumerated type.  This warning is enabled by @option{-Wextra}
 in C@.
 
+@item -Wenum-int-mismatch @r{(C and Objective-C only)}
+@opindex Wenum-int-mismatch
+@opindex Wno-enum-int-mismatch
+Warn about mismatches between an enumerated type and an integer type in
+declarations.  For example:
+
+@smallexample
+enum E @{ l = -1, z = 0, g = 1 @};
+int foo(void);
+enum E foo(void);
+@end smallexample
+
+In C, an enumerated type is compatible with @code{char}, a signed
+integer type, or an unsigned integer type.  However, since the choice
+of the underlying type of an enumerated type is implementation-defined,
+such mismatches may cause portability issues.  In C++, such mismatches
+are an error.  In C, this warning is enabled by @option{-Wall}.
+
 @item -Wjump-misses-init @r{(C, Objective-C only)}
 @opindex Wjump-misses-init
 @opindex Wno-jump-misses-init
diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c
new file mode 100644
index 00000000000..f71a308bc19
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c
@@ -0,0 +1,35 @@
+/* PR c/105131 */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+enum E { l = -1, z = 0, g = 1 };
+
+int foo(void); /* { dg-message "previous declaration" } */
+enum E foo(void) { return z; } /* { dg-warning "conflicting types" } */
+
+void bar(int); /* { dg-message "previous declaration" } */
+void bar(enum E); /* { dg-warning "conflicting types" } */
+
+extern int arr[10]; /* { dg-message "previous declaration" } */
+extern enum E arr[10]; /* { dg-warning "conflicting types" } */
+
+extern int i; /* { dg-message "previous declaration" } */
+extern enum E i; /* { dg-warning "conflicting types" } */
+
+extern int *p; /* { dg-message "previous declaration" } */
+extern enum E *p; /* { dg-warning "conflicting types" } */
+
+enum E foo2(void) { return z; } /* { dg-message "previous definition" } */
+int foo2(void); /* { dg-warning "conflicting types" } */
+
+void bar2(enum E); /* { dg-message "previous declaration" } */
+void bar2(int); /* { dg-warning "conflicting types" } */
+
+extern enum E arr2[10]; /* { dg-message "previous declaration" } */
+extern int arr2[10]; /* { dg-warning "conflicting types" } */
+
+extern enum E i2; /* { dg-message "previous declaration" } */
+extern int i2; /* { dg-warning "conflicting types" } */
+
+extern enum E *p2; /* { dg-message "previous declaration" } */
+extern int *p2; /* { dg-warning "conflicting types" } */
diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c
new file mode 100644
index 00000000000..7296b703672
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c
@@ -0,0 +1,35 @@
+/* PR c/105131 */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+enum E { l = 0, z, g };
+
+unsigned int foo(void); /* { dg-message "previous declaration" } */
+enum E foo(void) { return z; } /* { dg-warning "conflicting types" } */
+
+void bar(unsigned int); /* { dg-message "previous declaration" } */
+void bar(enum E); /* { dg-warning "conflicting types" } */
+
+extern enum E arr[10]; /* { dg-message "previous declaration" } */
+extern unsigned int arr[10]; /* { dg-warning "conflicting types" } */
+
+extern unsigned int i; /* { dg-message "previous declaration" } */
+extern enum E i; /* { dg-warning "conflicting types" } */
+
+extern unsigned int *p; /* { dg-message "previous declaration" } */
+extern enum E *p; /* { dg-warning "conflicting types" } */
+
+enum E foo2(void) { return z; } /* { dg-message "previous definition" } */
+unsigned int foo2(void); /* { dg-warning "conflicting types" } */
+
+void bar2(enum E); /* { dg-message "previous declaration" } */
+void bar2(unsigned int); /* { dg-warning "conflicting types" } */
+
+extern unsigned int arr2[10]; /* { dg-message "previous declaration" } */
+extern enum E arr2[10]; /* { dg-warning "conflicting types" } */
+
+extern enum E i2; /* { dg-message "previous declaration" } */
+extern unsigned int i2; /* { dg-warning "conflicting types" } */
+
+extern enum E *p2; /* { dg-message "previous declaration" } */
+extern unsigned int *p2; /* { dg-warning "conflicting types" } */

base-commit: 2b0c8377729a3c62a05897136666574ab939aaab
-- 
2.36.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] c: Implement new -Wenum-int-mismatch warning [PR105131]
  2022-05-17 23:56 [PATCH] c: Implement new -Wenum-int-mismatch warning [PR105131] Marek Polacek
@ 2022-05-18 10:14 ` Pedro Alves
  2022-05-18 14:48   ` [PATCH v2] " Marek Polacek
  0 siblings, 1 reply; 6+ messages in thread
From: Pedro Alves @ 2022-05-18 10:14 UTC (permalink / raw)
  To: Marek Polacek, GCC Patches, Joseph Myers

On 2022-05-18 00:56, Marek Polacek via Gcc-patches wrote:

> +In C, an enumerated type is compatible with @code{char}, a signed
> +integer type, or an unsigned integer type.  However, since the choice
> +of the underlying type of an enumerated type is implementation-defined,
> +such mismatches may cause portability issues.  In C++, such mismatches
> +are an error.  In C, this warning is enabled by @option{-Wall}.

Should it also be enabled by -Wc++-compat?

Pedro Alves

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2] c: Implement new -Wenum-int-mismatch warning [PR105131]
  2022-05-18 10:14 ` Pedro Alves
@ 2022-05-18 14:48   ` Marek Polacek
  2022-05-18 20:58     ` Joseph Myers
  0 siblings, 1 reply; 6+ messages in thread
From: Marek Polacek @ 2022-05-18 14:48 UTC (permalink / raw)
  To: Pedro Alves; +Cc: GCC Patches, Joseph Myers

On Wed, May 18, 2022 at 11:14:25AM +0100, Pedro Alves wrote:
> On 2022-05-18 00:56, Marek Polacek via Gcc-patches wrote:
> 
> > +In C, an enumerated type is compatible with @code{char}, a signed
> > +integer type, or an unsigned integer type.  However, since the choice
> > +of the underlying type of an enumerated type is implementation-defined,
> > +such mismatches may cause portability issues.  In C++, such mismatches
> > +are an error.  In C, this warning is enabled by @option{-Wall}.
> 
> Should it also be enabled by -Wc++-compat?

Yes, that's a good idea.  Fixed here:

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
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/c-family/c.opt                          |  4 +++
 gcc/c/c-decl.cc                             | 13 ++++++--
 gcc/c/c-tree.h                              |  1 +
 gcc/c/c-typeck.cc                           |  2 +-
 gcc/doc/invoke.texi                         | 21 +++++++++++++
 gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c | 35 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c | 35 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c | 35 +++++++++++++++++++++
 8 files changed, 143 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c
 create mode 100644 gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c
 create mode 100644 gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 035b1de0d84..41a20bc625e 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -638,6 +638,10 @@ Wenum-conversion
 C ObjC C++ ObjC++ Var(warn_enum_conversion) Init(0) Warning LangEnabledBy(C ObjC,Wextra)
 Warn about implicit conversion of enum types.
 
+Wenum-int-mismatch
+C ObjC Var(warn_enum_int_mismatch) Warning LangEnabledBy(C ObjC,Wall || Wc++-compat)
+Warn about enum/integer type mismatches.
+
 Werror
 C ObjC C++ ObjC++
 ; Documented in common.opt
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 83655548fc4..5266a61b859 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -1993,9 +1993,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)
@@ -2137,6 +2140,13 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
 	  return false;
 	}
     }
+  /* Warn about enum/integer type mismatches.  They are compatible types
+     (C2X 6.7.2.2/5), but may pose portability problems.  */
+  else if (enum_and_int_p && TREE_CODE (newdecl) != TYPE_DECL)
+    warned = warning_at (DECL_SOURCE_LOCATION (newdecl),
+			 OPT_Wenum_int_mismatch,
+			 "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
@@ -2146,7 +2156,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 bcfe08b82bc..4f3611f1b89 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;
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e8e6d4e039b..98a543ae06f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -349,6 +349,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wno-div-by-zero  -Wdouble-promotion @gol
 -Wduplicated-branches  -Wduplicated-cond @gol
 -Wempty-body  -Wno-endif-labels  -Wenum-compare  -Wenum-conversion @gol
+-Wenum-int-mismatch @gol
 -Werror  -Werror=*  -Wexpansion-to-defined  -Wfatal-errors @gol
 -Wfloat-conversion  -Wfloat-equal  -Wformat  -Wformat=2 @gol
 -Wno-format-contains-nul  -Wno-format-extra-args  @gol
@@ -5759,6 +5760,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
 -Wdangling-pointer=2  @gol
 -Wduplicate-decl-specifier @r{(C and Objective-C only)} @gol
 -Wenum-compare @r{(in C/ObjC; this is on by default in C++)} @gol
+-Wenum-int-mismatch @r{(C and Objective-C only)} @gol
 -Wformat   @gol
 -Wformat-overflow  @gol
 -Wformat-truncation  @gol
@@ -8735,6 +8737,25 @@ Warn when a value of enumerated type is implicitly converted to a
 different enumerated type.  This warning is enabled by @option{-Wextra}
 in C@.
 
+@item -Wenum-int-mismatch @r{(C and Objective-C only)}
+@opindex Wenum-int-mismatch
+@opindex Wno-enum-int-mismatch
+Warn about mismatches between an enumerated type and an integer type in
+declarations.  For example:
+
+@smallexample
+enum E @{ l = -1, z = 0, g = 1 @};
+int foo(void);
+enum E foo(void);
+@end smallexample
+
+In C, an enumerated type is compatible with @code{char}, a signed
+integer type, or an unsigned integer type.  However, since the choice
+of the underlying type of an enumerated type is implementation-defined,
+such mismatches may cause portability issues.  In C++, such mismatches
+are an error.  In C, this warning is enabled by @option{-Wall} and
+@option{-Wc++-compat}.
+
 @item -Wjump-misses-init @r{(C, Objective-C only)}
 @opindex Wjump-misses-init
 @opindex Wno-jump-misses-init
diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c
new file mode 100644
index 00000000000..f71a308bc19
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c
@@ -0,0 +1,35 @@
+/* PR c/105131 */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+enum E { l = -1, z = 0, g = 1 };
+
+int foo(void); /* { dg-message "previous declaration" } */
+enum E foo(void) { return z; } /* { dg-warning "conflicting types" } */
+
+void bar(int); /* { dg-message "previous declaration" } */
+void bar(enum E); /* { dg-warning "conflicting types" } */
+
+extern int arr[10]; /* { dg-message "previous declaration" } */
+extern enum E arr[10]; /* { dg-warning "conflicting types" } */
+
+extern int i; /* { dg-message "previous declaration" } */
+extern enum E i; /* { dg-warning "conflicting types" } */
+
+extern int *p; /* { dg-message "previous declaration" } */
+extern enum E *p; /* { dg-warning "conflicting types" } */
+
+enum E foo2(void) { return z; } /* { dg-message "previous definition" } */
+int foo2(void); /* { dg-warning "conflicting types" } */
+
+void bar2(enum E); /* { dg-message "previous declaration" } */
+void bar2(int); /* { dg-warning "conflicting types" } */
+
+extern enum E arr2[10]; /* { dg-message "previous declaration" } */
+extern int arr2[10]; /* { dg-warning "conflicting types" } */
+
+extern enum E i2; /* { dg-message "previous declaration" } */
+extern int i2; /* { dg-warning "conflicting types" } */
+
+extern enum E *p2; /* { dg-message "previous declaration" } */
+extern int *p2; /* { dg-warning "conflicting types" } */
diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c
new file mode 100644
index 00000000000..7296b703672
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c
@@ -0,0 +1,35 @@
+/* PR c/105131 */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+enum E { l = 0, z, g };
+
+unsigned int foo(void); /* { dg-message "previous declaration" } */
+enum E foo(void) { return z; } /* { dg-warning "conflicting types" } */
+
+void bar(unsigned int); /* { dg-message "previous declaration" } */
+void bar(enum E); /* { dg-warning "conflicting types" } */
+
+extern enum E arr[10]; /* { dg-message "previous declaration" } */
+extern unsigned int arr[10]; /* { dg-warning "conflicting types" } */
+
+extern unsigned int i; /* { dg-message "previous declaration" } */
+extern enum E i; /* { dg-warning "conflicting types" } */
+
+extern unsigned int *p; /* { dg-message "previous declaration" } */
+extern enum E *p; /* { dg-warning "conflicting types" } */
+
+enum E foo2(void) { return z; } /* { dg-message "previous definition" } */
+unsigned int foo2(void); /* { dg-warning "conflicting types" } */
+
+void bar2(enum E); /* { dg-message "previous declaration" } */
+void bar2(unsigned int); /* { dg-warning "conflicting types" } */
+
+extern unsigned int arr2[10]; /* { dg-message "previous declaration" } */
+extern enum E arr2[10]; /* { dg-warning "conflicting types" } */
+
+extern enum E i2; /* { dg-message "previous declaration" } */
+extern unsigned int i2; /* { dg-warning "conflicting types" } */
+
+extern enum E *p2; /* { dg-message "previous declaration" } */
+extern unsigned int *p2; /* { dg-warning "conflicting types" } */
diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c
new file mode 100644
index 00000000000..8773f01869c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c
@@ -0,0 +1,35 @@
+/* PR c/105131 */
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat" } */
+
+enum E { l = -1, z = 0, g = 1 };
+
+int foo(void); /* { dg-message "previous declaration" } */
+enum E foo(void) { return z; } /* { dg-warning "conflicting types" } */
+
+void bar(int); /* { dg-message "previous declaration" } */
+void bar(enum E); /* { dg-warning "conflicting types" } */
+
+extern int arr[10]; /* { dg-message "previous declaration" } */
+extern enum E arr[10]; /* { dg-warning "conflicting types" } */
+
+extern int i; /* { dg-message "previous declaration" } */
+extern enum E i; /* { dg-warning "conflicting types" } */
+
+extern int *p; /* { dg-message "previous declaration" } */
+extern enum E *p; /* { dg-warning "conflicting types" } */
+
+enum E foo2(void) { return z; } /* { dg-message "previous definition" } */
+int foo2(void); /* { dg-warning "conflicting types" } */
+
+void bar2(enum E); /* { dg-message "previous declaration" } */
+void bar2(int); /* { dg-warning "conflicting types" } */
+
+extern enum E arr2[10]; /* { dg-message "previous declaration" } */
+extern int arr2[10]; /* { dg-warning "conflicting types" } */
+
+extern enum E i2; /* { dg-message "previous declaration" } */
+extern int i2; /* { dg-warning "conflicting types" } */
+
+extern enum E *p2; /* { dg-message "previous declaration" } */
+extern int *p2; /* { dg-warning "conflicting types" } */

base-commit: 60fdce11dc9e5ddf671b07a3fc6ed70476860b22
-- 
2.36.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] c: Implement new -Wenum-int-mismatch warning [PR105131]
  2022-05-18 14:48   ` [PATCH v2] " Marek Polacek
@ 2022-05-18 20:58     ` Joseph Myers
  2022-05-18 21:51       ` [PATCH v3] " Marek Polacek
  0 siblings, 1 reply; 6+ messages in thread
From: Joseph Myers @ 2022-05-18 20:58 UTC (permalink / raw)
  To: Marek Polacek; +Cc: Pedro Alves, GCC Patches

On Wed, 18 May 2022, Marek Polacek via Gcc-patches wrote:

> diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c
> new file mode 100644
> index 00000000000..f71a308bc19
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c
> @@ -0,0 +1,35 @@
> +/* PR c/105131 */
> +/* { dg-do compile } */
> +/* { dg-options "-Wall" } */

Since some Arm targets default to -fshort-enums, I think it would be best 
for the tests to use -fno-short-enums or otherwise ensure the enums are 
compatible with the expected type, so that they test what's intended.  
Additional tests that don't use the -W options but #include the main tests 
might also be a good idea, to verify that all the types in the tests 
really are compatible as intended.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v3] c: Implement new -Wenum-int-mismatch warning [PR105131]
  2022-05-18 20:58     ` Joseph Myers
@ 2022-05-18 21:51       ` Marek Polacek
  2022-05-18 22:25         ` Joseph Myers
  0 siblings, 1 reply; 6+ messages in thread
From: Marek Polacek @ 2022-05-18 21:51 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Pedro Alves, GCC Patches

On Wed, May 18, 2022 at 08:58:02PM +0000, Joseph Myers wrote:
> On Wed, 18 May 2022, Marek Polacek via Gcc-patches wrote:
> 
> > diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c
> > new file mode 100644
> > index 00000000000..f71a308bc19
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c
> > @@ -0,0 +1,35 @@
> > +/* PR c/105131 */
> > +/* { dg-do compile } */
> > +/* { dg-options "-Wall" } */
> 
> Since some Arm targets default to -fshort-enums, I think it would be best 
> for the tests to use -fno-short-enums or otherwise ensure the enums are 
> compatible with the expected type, so that they test what's intended.  

You're right, the tests would likely break on ARM because of that.
I've added -fno-short-enums.

> Additional tests that don't use the -W options but #include the main tests 
> might also be a good idea, to verify that all the types in the tests 
> really are compatible as intended.

I've extended the tests to use an enum with __attribute__ ((__packed__)) to
test the case when the underlying type is (un)signed char.  But it seems like
we can't have underlying types wider than int.  I've also included two tests
which #include the two main tests.  Seems like Dejagnu doesn't expect the
diagnostics as per the dg directives in the main tests, which is good.

Is the following ok?

Thanks,

-- >8 --
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                          |  4 ++
 gcc/c/c-decl.cc                             | 13 ++++++-
 gcc/c/c-tree.h                              |  1 +
 gcc/c/c-typeck.cc                           |  2 +-
 gcc/doc/invoke.texi                         | 21 ++++++++++
 gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c | 43 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c | 43 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c | 43 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/Wenum-int-mismatch-4.c |  5 +++
 gcc/testsuite/gcc.dg/Wenum-int-mismatch-5.c |  5 +++
 10 files changed, 177 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c
 create mode 100644 gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c
 create mode 100644 gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c
 create mode 100644 gcc/testsuite/gcc.dg/Wenum-int-mismatch-4.c
 create mode 100644 gcc/testsuite/gcc.dg/Wenum-int-mismatch-5.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 035b1de0d84..41a20bc625e 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -638,6 +638,10 @@ Wenum-conversion
 C ObjC C++ ObjC++ Var(warn_enum_conversion) Init(0) Warning LangEnabledBy(C ObjC,Wextra)
 Warn about implicit conversion of enum types.
 
+Wenum-int-mismatch
+C ObjC Var(warn_enum_int_mismatch) Warning LangEnabledBy(C ObjC,Wall || Wc++-compat)
+Warn about enum/integer type mismatches.
+
 Werror
 C ObjC C++ ObjC++
 ; Documented in common.opt
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 83655548fc4..5266a61b859 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -1993,9 +1993,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)
@@ -2137,6 +2140,13 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
 	  return false;
 	}
     }
+  /* Warn about enum/integer type mismatches.  They are compatible types
+     (C2X 6.7.2.2/5), but may pose portability problems.  */
+  else if (enum_and_int_p && TREE_CODE (newdecl) != TYPE_DECL)
+    warned = warning_at (DECL_SOURCE_LOCATION (newdecl),
+			 OPT_Wenum_int_mismatch,
+			 "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
@@ -2146,7 +2156,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 bcfe08b82bc..4f3611f1b89 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;
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e8e6d4e039b..98a543ae06f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -349,6 +349,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wno-div-by-zero  -Wdouble-promotion @gol
 -Wduplicated-branches  -Wduplicated-cond @gol
 -Wempty-body  -Wno-endif-labels  -Wenum-compare  -Wenum-conversion @gol
+-Wenum-int-mismatch @gol
 -Werror  -Werror=*  -Wexpansion-to-defined  -Wfatal-errors @gol
 -Wfloat-conversion  -Wfloat-equal  -Wformat  -Wformat=2 @gol
 -Wno-format-contains-nul  -Wno-format-extra-args  @gol
@@ -5759,6 +5760,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
 -Wdangling-pointer=2  @gol
 -Wduplicate-decl-specifier @r{(C and Objective-C only)} @gol
 -Wenum-compare @r{(in C/ObjC; this is on by default in C++)} @gol
+-Wenum-int-mismatch @r{(C and Objective-C only)} @gol
 -Wformat   @gol
 -Wformat-overflow  @gol
 -Wformat-truncation  @gol
@@ -8735,6 +8737,25 @@ Warn when a value of enumerated type is implicitly converted to a
 different enumerated type.  This warning is enabled by @option{-Wextra}
 in C@.
 
+@item -Wenum-int-mismatch @r{(C and Objective-C only)}
+@opindex Wenum-int-mismatch
+@opindex Wno-enum-int-mismatch
+Warn about mismatches between an enumerated type and an integer type in
+declarations.  For example:
+
+@smallexample
+enum E @{ l = -1, z = 0, g = 1 @};
+int foo(void);
+enum E foo(void);
+@end smallexample
+
+In C, an enumerated type is compatible with @code{char}, a signed
+integer type, or an unsigned integer type.  However, since the choice
+of the underlying type of an enumerated type is implementation-defined,
+such mismatches may cause portability issues.  In C++, such mismatches
+are an error.  In C, this warning is enabled by @option{-Wall} and
+@option{-Wc++-compat}.
+
 @item -Wjump-misses-init @r{(C, Objective-C only)}
 @opindex Wjump-misses-init
 @opindex Wno-jump-misses-init
diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c
new file mode 100644
index 00000000000..629801833de
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c
@@ -0,0 +1,43 @@
+/* PR c/105131 */
+/* { dg-do compile } */
+/* { dg-options "-Wall -fno-short-enums" } */
+
+enum E { E1 = -1, E2 = 0, E3 = 1 };
+
+int foo(void); /* { dg-message "previous declaration" } */
+enum E foo(void) { return E2; } /* { dg-warning "conflicting types" } */
+
+void bar(int); /* { dg-message "previous declaration" } */
+void bar(enum E); /* { dg-warning "conflicting types" } */
+
+extern int arr[10]; /* { dg-message "previous declaration" } */
+extern enum E arr[10]; /* { dg-warning "conflicting types" } */
+
+extern int i; /* { dg-message "previous declaration" } */
+extern enum E i; /* { dg-warning "conflicting types" } */
+
+extern int *p; /* { dg-message "previous declaration" } */
+extern enum E *p; /* { dg-warning "conflicting types" } */
+
+enum E foo2(void) { return E2; } /* { dg-message "previous definition" } */
+int foo2(void); /* { dg-warning "conflicting types" } */
+
+void bar2(enum E); /* { dg-message "previous declaration" } */
+void bar2(int); /* { dg-warning "conflicting types" } */
+
+extern enum E arr2[10]; /* { dg-message "previous declaration" } */
+extern int arr2[10]; /* { dg-warning "conflicting types" } */
+
+extern enum E i2; /* { dg-message "previous declaration" } */
+extern int i2; /* { dg-warning "conflicting types" } */
+
+extern enum E *p2; /* { dg-message "previous declaration" } */
+extern int *p2; /* { dg-warning "conflicting types" } */
+
+enum F { F1 = -1, F2, F3 } __attribute__ ((__packed__));
+
+enum F fn1(void); /* { dg-message "previous declaration" } */
+signed char fn1(void); /* { dg-warning "conflicting types" } */
+
+signed char fn2(void); /* { dg-message "previous declaration" } */
+enum F fn2(void); /* { dg-warning "conflicting types" } */
diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c
new file mode 100644
index 00000000000..e5f75003d6a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c
@@ -0,0 +1,43 @@
+/* PR c/105131 */
+/* { dg-do compile } */
+/* { dg-options "-Wall -fno-short-enums" } */
+
+enum E { E1 = 0, E2, E3 };
+
+unsigned int foo(void); /* { dg-message "previous declaration" } */
+enum E foo(void) { return E2; } /* { dg-warning "conflicting types" } */
+
+void bar(unsigned int); /* { dg-message "previous declaration" } */
+void bar(enum E); /* { dg-warning "conflicting types" } */
+
+extern enum E arr[10]; /* { dg-message "previous declaration" } */
+extern unsigned int arr[10]; /* { dg-warning "conflicting types" } */
+
+extern unsigned int i; /* { dg-message "previous declaration" } */
+extern enum E i; /* { dg-warning "conflicting types" } */
+
+extern unsigned int *p; /* { dg-message "previous declaration" } */
+extern enum E *p; /* { dg-warning "conflicting types" } */
+
+enum E foo2(void) { return E2; } /* { dg-message "previous definition" } */
+unsigned int foo2(void); /* { dg-warning "conflicting types" } */
+
+void bar2(enum E); /* { dg-message "previous declaration" } */
+void bar2(unsigned int); /* { dg-warning "conflicting types" } */
+
+extern unsigned int arr2[10]; /* { dg-message "previous declaration" } */
+extern enum E arr2[10]; /* { dg-warning "conflicting types" } */
+
+extern enum E i2; /* { dg-message "previous declaration" } */
+extern unsigned int i2; /* { dg-warning "conflicting types" } */
+
+extern enum E *p2; /* { dg-message "previous declaration" } */
+extern unsigned int *p2; /* { dg-warning "conflicting types" } */
+
+enum F { F1 = 1u, F2, F3 } __attribute__ ((__packed__));
+
+enum F fn1(void); /* { dg-message "previous declaration" } */
+unsigned char fn1(void); /* { dg-warning "conflicting types" } */
+
+unsigned char fn2(void); /* { dg-message "previous declaration" } */
+enum F fn2(void); /* { dg-warning "conflicting types" } */
diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c
new file mode 100644
index 00000000000..4ddbeb152d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c
@@ -0,0 +1,43 @@
+/* PR c/105131 */
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat -fno-short-enums" } */
+
+enum E { E1 = -1, E2 = 0, E3 = 1 };
+
+int foo(void); /* { dg-message "previous declaration" } */
+enum E foo(void) { return E2; } /* { dg-warning "conflicting types" } */
+
+void bar(int); /* { dg-message "previous declaration" } */
+void bar(enum E); /* { dg-warning "conflicting types" } */
+
+extern int arr[10]; /* { dg-message "previous declaration" } */
+extern enum E arr[10]; /* { dg-warning "conflicting types" } */
+
+extern int i; /* { dg-message "previous declaration" } */
+extern enum E i; /* { dg-warning "conflicting types" } */
+
+extern int *p; /* { dg-message "previous declaration" } */
+extern enum E *p; /* { dg-warning "conflicting types" } */
+
+enum E foo2(void) { return E2; } /* { dg-message "previous definition" } */
+int foo2(void); /* { dg-warning "conflicting types" } */
+
+void bar2(enum E); /* { dg-message "previous declaration" } */
+void bar2(int); /* { dg-warning "conflicting types" } */
+
+extern enum E arr2[10]; /* { dg-message "previous declaration" } */
+extern int arr2[10]; /* { dg-warning "conflicting types" } */
+
+extern enum E i2; /* { dg-message "previous declaration" } */
+extern int i2; /* { dg-warning "conflicting types" } */
+
+extern enum E *p2; /* { dg-message "previous declaration" } */
+extern int *p2; /* { dg-warning "conflicting types" } */
+
+enum F { F1 = -1, F2, F3 } __attribute__ ((__packed__));
+
+enum F fn1(void); /* { dg-message "previous declaration" } */
+signed char fn1(void); /* { dg-warning "conflicting types" } */
+
+signed char fn2(void); /* { dg-message "previous declaration" } */
+enum F fn2(void); /* { dg-warning "conflicting types" } */
diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-4.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-4.c
new file mode 100644
index 00000000000..fcaca283457
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-4.c
@@ -0,0 +1,5 @@
+/* PR c/105131 */
+/* { dg-do compile } */
+/* { dg-options "-fno-short-enums" } */
+
+#include "Wenum-int-mismatch-1.c"
diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-5.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-5.c
new file mode 100644
index 00000000000..db24fd32f00
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-5.c
@@ -0,0 +1,5 @@
+/* PR c/105131 */
+/* { dg-do compile } */
+/* { dg-options "-fno-short-enums" } */
+
+#include "Wenum-int-mismatch-2.c"

base-commit: 1875214cd1ca3e8bd0121f703537eb98edd84027
-- 
2.36.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] c: Implement new -Wenum-int-mismatch warning [PR105131]
  2022-05-18 21:51       ` [PATCH v3] " Marek Polacek
@ 2022-05-18 22:25         ` Joseph Myers
  0 siblings, 0 replies; 6+ messages in thread
From: Joseph Myers @ 2022-05-18 22:25 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches, Pedro Alves

On Wed, 18 May 2022, Marek Polacek via Gcc-patches wrote:

> I've extended the tests to use an enum with __attribute__ ((__packed__)) to
> test the case when the underlying type is (un)signed char.  But it seems like
> we can't have underlying types wider than int.  I've also included two tests
> which #include the two main tests.  Seems like Dejagnu doesn't expect the
> diagnostics as per the dg directives in the main tests, which is good.
> 
> Is the following ok?

OK.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-05-18 22:25 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-17 23:56 [PATCH] c: Implement new -Wenum-int-mismatch warning [PR105131] Marek Polacek
2022-05-18 10:14 ` Pedro Alves
2022-05-18 14:48   ` [PATCH v2] " Marek Polacek
2022-05-18 20:58     ` Joseph Myers
2022-05-18 21:51       ` [PATCH v3] " Marek Polacek
2022-05-18 22:25         ` Joseph Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).