https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117122
Bug ID: 117122 Summary: -funsigned-bitfields has incorrect behavior with typeof and typedef redefinitions Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- With -funsigned-bitfields, the types signed and int are not the same. However, GCC doesn't propogate this information correctly with typeof: #include<stdio.h> int main(void){ struct S{ typeof(signed)x:10; typeof((signed)0)y:10; typeof(0)z:10; }a={-1,-1,-1}; printf("%i %i %i\n",a.x,a.y,a.z); } With this program GCC prints "1023 1023 1023" when it should print "-1 -1 -1". > The typeof specifier applies the typeof operators to an expression (6.5.1) or > a type name. If the typeof operators are applied to an expression, they yield > the type of their operand. Otherwise, they designate the same type as the type > name with any nested typeof specifier evaluated. If the type of the operand is > a variably modified type, the operand is evaluated; otherwise, the operand is > not evaluated. Section 6.7.3.6 "Typeof specifiers" Paragraph 4 N3220 typeof(signed)x:10 should be the same type as signed x:10 here, not int x:10. The second member declaration demonstrates the same thing with expressions. Perhaps typeof(0) should be able to be unsigned in a bit-field declaration, because the standard describes the type as int instead of signed in the table of integer literal types. However, doing this would result in cases like typeof((signed)0+0) being unclear so I don't think it makes sense. Additionally, in typedef redefinitions GCC will allow changing the type between signed and int: #include<stdio.h> int main(void){ typedef signed T; struct A{T x:10;}a={-1}; typedef int T; struct B{T x:10;}b={-1}; typedef signed T; struct C{T x:10;}c={-1}; printf("%i %i %i\n",a.x,b.x,c.x); } With this program GCC prints "-1 1023 -1", clearly the types signed and int here are distinct. Shouldn't this program violate the constraint that typedef redefinitions must be the same type? > If an identifier has no linkage, there shall be no more than one declaration > of the identifier (in a declarator or type specifier) with the same scope and > in the same name space, except that: > > - a typedef name may be redefined to denote the same type as it currently > does, provided that type is not a variably modified type; > > - enumeration constants and tags may be redeclared as specified in 6.7.3.3 and > 6.7.3.4, respectively. Section 6.7.1 "General" Paragraph 4 N3220 If this program doesn't violate this constraint, I think it would be at least useful to give a warning here because the behavior seems quite strange.