Module Name: src Committed By: rillig Date: Sat Jan 28 08:30:12 UTC 2023
Modified Files: src/tests/usr.bin/xlint/lint1: gcc_bit_field_types.c Log Message: tests/lint: investigate how compilers interpret bit-fields To generate a diff of this commit: cvs rdiff -u -r1.6 -r1.7 src/tests/usr.bin/xlint/lint1/gcc_bit_field_types.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/usr.bin/xlint/lint1/gcc_bit_field_types.c diff -u src/tests/usr.bin/xlint/lint1/gcc_bit_field_types.c:1.6 src/tests/usr.bin/xlint/lint1/gcc_bit_field_types.c:1.7 --- src/tests/usr.bin/xlint/lint1/gcc_bit_field_types.c:1.6 Sat Jan 15 14:22:03 2022 +++ src/tests/usr.bin/xlint/lint1/gcc_bit_field_types.c Sat Jan 28 08:30:12 2023 @@ -1,6 +1,11 @@ -/* $NetBSD: gcc_bit_field_types.c,v 1.6 2022/01/15 14:22:03 rillig Exp $ */ +/* $NetBSD: gcc_bit_field_types.c,v 1.7 2023/01/28 08:30:12 rillig Exp $ */ # 3 "gcc_bit_field_types.c" +struct incompatible { + int dummy; +}; +void reveal_type(struct incompatible); + /* * https://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit-fields-implementation.html * @@ -35,3 +40,59 @@ promote_large_bit_field(struct large_bit */ return lbf.member & 0xf; } + +/* + * C99 6.7.2.1p4 says: "A bit-field shall have a type that is a qualified or + * unqualified version of _Bool, signed int, unsigned int, or some other + * implementation-defined type." + * + * The wording of that constraint does not disambiguate whether it is talking + * about the declared underlying type of the storage unit or the expression + * type when evaluating a bit-field as an rvalue. + */ +void +type_of_bit_field(void) +{ + struct { + unsigned bits:3; + } s; + + /* + * Lint interprets the type of the bit-field is 'unsigned:3', which + * matches the non-bit-field type 'unsigned' in the _Generic + * expression. (XXX: May or may not be intended.) + * + * The _Generic expression prevents the integer promotions from + * getting applied as part of the function argument conversions. + * + * GCC 11 says: error: '_Generic' selector of type 'unsigned char:3' + * is not compatible with any association + * + * Clang 15 says: error: controlling expression type 'unsigned int' + * not compatible with any generic association type + * + * TCC says: error: type 'unsigned int' does not match any association + * + * MSVC 19 says: error C7702: no compatible type for 'unsigned int' + * in _Generic association list + * + * ICC 2021.7.1 says: error: no association matches the selector type + * "unsigned int" + */ + /* expect+4: warning: passing 'pointer to unsigned int' to incompatible 'struct incompatible', arg #1 [155] */ + reveal_type(_Generic(s.bits, + int: (int *)0, + unsigned int: (unsigned int *)0 + )); + + /* + * When lint promotes the bit-field as part of the function argument + * conversions, the type 'unsigned:3' gets promoted to 'int', as that + * is the smallest candidate type that can represent all possible + * values from 'unsigned:3', see promote_c90. Maybe that's wrong, + * maybe not, the compilers disagree so lint can offer yet another + * alternative interpretation. + */ + /* expect+1: warning: passing 'unsigned int:3' to incompatible 'struct incompatible', arg #1 [155] */ + reveal_type(s.bits); +}