diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-10-30 14:51:02 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2024-10-30 14:51:02 +0100 |
commit | d7f2c1bff6993cba1e46fd6902776778612c290d (patch) | |
tree | 8cd9855d9ea9770805896f12b2ec1cf970888aff | |
parent | a65e1487cda969e4763ae84577bf3e0d9e2b34aa (diff) | |
download | gcc-d7f2c1bff6993cba1e46fd6902776778612c290d.zip gcc-d7f2c1bff6993cba1e46fd6902776778612c290d.tar.gz gcc-d7f2c1bff6993cba1e46fd6902776778612c290d.tar.bz2 |
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 <jakub@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.
-rw-r--r-- | gcc/c/c-parser.cc | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtin-stdc-bit-3.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtin-stdc-rotate-3.c | 9 |
3 files changed, 38 insertions, 0 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 88dd0be..90c3397 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 0000000..bb73768 --- /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 0000000..6eac145 --- /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" } */ +} |