Allow it syntactically, but diagnose it with a new -Wmaxof-bool, enabled
by -Wextra.

gcc/c-family/ChangeLog:

        * c-common.cc (c_maxof_type, c_minof_type): Allow and warn bool.
        * c.opt: Add -Wmaxof-bool.

gcc/ChangeLog:

        * doc/invoke.texi: Document the new -Wmaxof-bool.

gcc/testsuite/ChangeLog:

        * gcc.dg/Wmaxof-bool.c: New test.
        * gcc.dg/maxof-compile.c: Update test.

Signed-off-by: Alejandro Colomar <[email protected]>
---
 gcc/c-family/c-common.cc             |  8 ++++++--
 gcc/c-family/c.opt                   |  5 +++++
 gcc/doc/invoke.texi                  | 10 ++++++++++
 gcc/testsuite/gcc.dg/Wmaxof-bool.c   |  8 ++++++++
 gcc/testsuite/gcc.dg/maxof-compile.c |  8 ++++++--
 5 files changed, 35 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wmaxof-bool.c

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 00e521974f22..33643007f300 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -4146,11 +4146,13 @@ c_countof_type (location_t loc, tree type)
 tree
 c_maxof_type (location_t loc, tree type)
 {
-  if (!INTEGRAL_TYPE_P (type) || TREE_CODE (type) == BOOLEAN_TYPE)
+  if (!INTEGRAL_TYPE_P (type))
     {
       error_at (loc, "invalid application of %<_Maxof%> to type %qT", type);
       return error_mark_node;
     }
+  if (TREE_CODE (type) == BOOLEAN_TYPE)
+    warning_at (loc, OPT_Wmaxof_bool, "%<_Maxof%> applied to type %qT", type);
 
   return TYPE_MAX_VALUE (type);
 }
@@ -4161,11 +4163,13 @@ c_maxof_type (location_t loc, tree type)
 tree
 c_minof_type (location_t loc, tree type)
 {
-  if (!INTEGRAL_TYPE_P (type) || TREE_CODE (type) == BOOLEAN_TYPE)
+  if (!INTEGRAL_TYPE_P (type))
     {
       error_at (loc, "invalid application of %<_Minof%> to type %qT", type);
       return error_mark_node;
     }
+  if (TREE_CODE (type) == BOOLEAN_TYPE)
+    warning_at (loc, OPT_Wmaxof_bool, "%<_Minof%> applied to type %qT", type);
 
   return TYPE_MIN_VALUE (type);
 }
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 0d97b0d13ce5..746b042180e7 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1004,6 +1004,11 @@ Wmain
 LangEnabledBy(C ObjC C++ ObjC++,Wpedantic, 2, 0)
 ;
 
+Wmaxof-bool
+C Var(warn_maxof_bool) Warning EnabledBy(Wextra)
+Warn on _Maxof(bool) and _Minof(bool).
+Warn when _Maxof or _Minof are applied to the type bool.
+
 Wmaybe-uninitialized
 C ObjC C++ ObjC++ LTO LangEnabledBy(C ObjC C++ ObjC++ LTO,Wall)
 ;
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index df4331fbad07..4446fc4a93c4 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -417,6 +417,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wlarger-than=@var{byte-size}  -Wleading-whitespace=@var{kind}
 -Wlogical-not-parentheses  -Wlogical-op
 -Wlong-long  -Wno-lto-type-mismatch -Wmain  -Wmaybe-uninitialized
+-Wmaxof-bool
 -Wmemset-elt-size  -Wmemset-transposed-args
 -Wmisleading-indentation  -Wmissing-attributes  -Wmissing-braces
 -Wmissing-field-initializers  -Wmissing-format-attribute
@@ -6841,6 +6842,7 @@ name is still supported, but the newer name is more 
descriptive.)
 -Wignored-qualifiers  @r{(only for C/C++)}
 -Wimplicit-fallthrough=3
 -Wmaybe-uninitialized
+-Wmaxof-bool
 -Wmissing-field-initializers
 -Wmissing-parameter-name @r{(C/ObjC only)}
 -Wmissing-parameter-type @r{(C/ObjC only)}
@@ -8562,6 +8564,14 @@ Attributes}.
 
 This warning is enabled by @option{-Wall} or @option{-Wextra}.
 
+@opindex Wmaxof-bool
+@opindex Wno-maxof-bool
+@item -Wmaxof-bool
+Warn when @code{_Maxof} or @code{_Minof}
+are applied to the type @code{bool}.
+
+This warning is enabled by @option{-Wextra}.
+
 @opindex Wunknown-pragmas
 @opindex Wno-unknown-pragmas
 @cindex warning for unknown pragmas
diff --git a/gcc/testsuite/gcc.dg/Wmaxof-bool.c 
b/gcc/testsuite/gcc.dg/Wmaxof-bool.c
new file mode 100644
index 000000000000..c468925836a6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wmaxof-bool.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-Wmaxof-bool" } */
+
+int main (void)
+{
+  bool b1 = _Maxof(bool);  /* { dg-warning "applied to type" } */
+  bool b2 = _Minof(bool);  /* { dg-warning "applied to type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/maxof-compile.c 
b/gcc/testsuite/gcc.dg/maxof-compile.c
index f59df75791bc..69fc76092289 100644
--- a/gcc/testsuite/gcc.dg/maxof-compile.c
+++ b/gcc/testsuite/gcc.dg/maxof-compile.c
@@ -46,6 +46,9 @@ integer (void)
   _Static_assert (_Minof (unsigned int) == 0);
   _Static_assert (_Minof (unsigned long) == 0);
   _Static_assert (_Minof (unsigned long long) == 0);
+
+  _Static_assert (_Maxof (bool) == true);
+  _Static_assert (_Minof (bool) == false);
 }
 
 void
@@ -98,8 +101,6 @@ non_int (void)
   _Minof (struct s);  /* { dg-error "to type" } */
   _Maxof (union u);  /* { dg-error "to type" } */
   _Minof (union u);  /* { dg-error "to type" } */
-  _Maxof (bool);  /* { dg-error "to type" } */
-  _Minof (bool);  /* { dg-error "to type" } */
   _Maxof (int [1]);  /* { dg-error "to type" } */
   _Minof (int [1]);  /* { dg-error "to type" } */
 }
@@ -152,6 +153,9 @@ type (void)
   _Generic (_Minof (unsigned long), unsigned long: 0);
   _Generic (_Minof (unsigned long long), unsigned long long: 0);
 
+  _Generic (_Maxof (bool), bool: 0);
+  _Generic (_Minof (bool), bool: 0);
+
   _Generic (_Maxof (_BitInt (5)), _BitInt (5): 0);
   _Generic (_Minof (_BitInt (5)), _BitInt (5): 0);
   _Generic (_Maxof (unsigned _BitInt (5)), unsigned _BitInt (5): 0);
-- 
2.51.0

Reply via email to