public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/105131] New: Warning for mismatched declaration/definition with enum
@ 2022-04-01 19:56 rth at gcc dot gnu.org
  2022-04-01 20:17 ` [Bug c/105131] " mpolacek at gcc dot gnu.org
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: rth at gcc dot gnu.org @ 2022-04-01 19:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105131

            Bug ID: 105131
           Summary: Warning for mismatched declaration/definition with
                    enum
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rth at gcc dot gnu.org
  Target Milestone: ---

For a testcase such as

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

If the implementation type of 'enum E' is not 'int',
we will correctly emit an error (e.g. -fshort-enums).

It would be desirable to emit a warning in this case,
because it is probably a mistake and definitely a
portability error.

^ 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
@ 2022-04-01 20:17 ` mpolacek at gcc dot gnu.org
  2022-04-01 20:59 ` mpolacek at gcc dot gnu.org
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2022-04-01 20:17 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105131

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2022-04-01
     Ever confirmed|0                           |1
           Keywords|                            |diagnostic
                 CC|                            |mpolacek at gcc dot gnu.org
             Status|UNCONFIRMED                 |NEW

--- Comment #1 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Confirmed.

^ 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
  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
  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
  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: mpolacek at gcc dot gnu.org @ 2022-05-17 20:34 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105131

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |mpolacek at gcc dot gnu.org
             Status|NEW                         |ASSIGNED

^ 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

* [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
                   ` (3 preceding siblings ...)
  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: mpolacek at gcc dot gnu.org @ 2022-05-18 23:14 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105131

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
             Status|ASSIGNED                    |RESOLVED

--- Comment #4 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Implemented in GCC 13.

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

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

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
2022-05-18 23:13 ` cvs-commit at gcc dot gnu.org
2022-05-18 23:14 ` mpolacek at gcc dot gnu.org

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).