https://gcc.gnu.org/g:d7f2c1bff6993cba1e46fd6902776778612c290d

commit r15-4780-gd7f2c1bff6993cba1e46fd6902776778612c290d
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Wed Oct 30 14:51:02 2024 +0100

    c: Diagnose char argument to __builtin_stdc_*
    
    When working on __builtin_stdc_rotate_*, I've noticed that while the
    second argument to those is explicitly allowed to have char type,
    the first argument to all the stdc_* type-generic functions is
    - standard unsigned integer type, excluding bool;
    - extended unsigned integer type;
    - or, bit-precise unsigned integer type whose width matches a standard
      or extended integer type, excluding bool.
    but the __builtin_stdc_* lowering code was diagnosing just
    !INTEGRAL_TYPE_P
    ENUMERAL_TYPE
    BOOLEAN_TYPE
    !TYPE_UNSIGNED
    Now, with -funsigned-char plain char type is TYPE_UNSIGNED, yet it isn't
    allowed because it isn't standard unsigned integer type, nor
    extended unsigned integer type, nor bit-precise unsigned integer type.
    
    The following patch diagnoses char arguments and adds testsuite coverage
    for that.
    
    Or should I make it a pedwarn instead?
    
    2024-10-30  Jakub Jelinek  <ja...@redhat.com>
    
    gcc/c/
            * c-parser.cc (c_parser_postfix_expression): Diagnose if
            first __builtin_stdc_* argument has char type even when
            -funsigned-char.
    gcc/testsuite/
            * gcc.dg/builtin-stdc-bit-3.c: New test.
            * gcc.dg/builtin-stdc-rotate-3.c: New test.

Diff:
---
 gcc/c/c-parser.cc                            |  8 ++++++++
 gcc/testsuite/gcc.dg/builtin-stdc-bit-3.c    | 21 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/builtin-stdc-rotate-3.c |  9 +++++++++
 3 files changed, 38 insertions(+)

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 88dd0be855c2..90c33970fda3 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -12382,6 +12382,14 @@ c_parser_postfix_expression (c_parser *parser)
                expr.set_error ();
                break;
              }
+           if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_p->value))
+               == char_type_node)
+             {
+               error_at (loc, "argument 1 in call to function "
+                         "%qs has %<char%> type", name);
+               expr.set_error ();
+               break;
+             }
            tree arg = arg_p->value;
            tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
            /* Expand:
diff --git a/gcc/testsuite/gcc.dg/builtin-stdc-bit-3.c 
b/gcc/testsuite/gcc.dg/builtin-stdc-bit-3.c
new file mode 100644
index 000000000000..bb73768840df
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-stdc-bit-3.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-funsigned-char" } */
+
+void
+foo (void)
+{
+  __builtin_stdc_leading_zeros ((char) 0);             /* { dg-error "argument 
1 in call to function '__builtin_stdc_leading_zeros' has 'char' type" } */
+  __builtin_stdc_leading_ones ((char) 0);              /* { dg-error "argument 
1 in call to function '__builtin_stdc_leading_ones' has 'char' type" } */
+  __builtin_stdc_trailing_zeros ((char) 0);            /* { dg-error "argument 
1 in call to function '__builtin_stdc_trailing_zeros' has 'char' type" } */
+  __builtin_stdc_trailing_ones ((char) 0);             /* { dg-error "argument 
1 in call to function '__builtin_stdc_trailing_ones' has 'char' type" } */
+  __builtin_stdc_first_leading_zero ((char) 0);                /* { dg-error 
"argument 1 in call to function '__builtin_stdc_first_leading_zero' has 'char' 
type" } */
+  __builtin_stdc_first_leading_one ((char) 0);         /* { dg-error "argument 
1 in call to function '__builtin_stdc_first_leading_one' has 'char' type" } */
+  __builtin_stdc_first_trailing_zero ((char) 0);       /* { dg-error "argument 
1 in call to function '__builtin_stdc_first_trailing_zero' has 'char' type" } */
+  __builtin_stdc_first_trailing_one ((char) 0);                /* { dg-error 
"argument 1 in call to function '__builtin_stdc_first_trailing_one' has 'char' 
type" } */
+  __builtin_stdc_count_zeros ((char) 0);               /* { dg-error "argument 
1 in call to function '__builtin_stdc_count_zeros' has 'char' type" } */
+  __builtin_stdc_count_ones ((char) 0);                        /* { dg-error 
"argument 1 in call to function '__builtin_stdc_count_ones' has 'char' type" } 
*/
+  __builtin_stdc_has_single_bit ((char) 0);            /* { dg-error "argument 
1 in call to function '__builtin_stdc_has_single_bit' has 'char' type" } */
+  __builtin_stdc_bit_width ((char) 0);                 /* { dg-error "argument 
1 in call to function '__builtin_stdc_bit_width' has 'char' type" } */
+  __builtin_stdc_bit_floor ((char) 0);                 /* { dg-error "argument 
1 in call to function '__builtin_stdc_bit_floor' has 'char' type" } */
+  __builtin_stdc_bit_ceil ((char) 0);                  /* { dg-error "argument 
1 in call to function '__builtin_stdc_bit_ceil' has 'char' type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-stdc-rotate-3.c 
b/gcc/testsuite/gcc.dg/builtin-stdc-rotate-3.c
new file mode 100644
index 000000000000..6eac145d205a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-stdc-rotate-3.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-funsigned-char" } */
+
+void
+foo (void)
+{
+  __builtin_stdc_rotate_left ((char) 0, 0);                    /* { dg-error 
"argument 1 in call to function '__builtin_stdc_rotate_left' has 'char' type" } 
*/
+  __builtin_stdc_rotate_right ((char) 0, 0);                   /* { dg-error 
"argument 1 in call to function '__builtin_stdc_rotate_right' has 'char' type" 
} */
+}

Reply via email to