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.