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.
  • [Bug c/117122] New: -funsigned-b... luigighiron at gmail dot com via Gcc-bugs

Reply via email to