Re: enums and EXPR_VALUE and sign expansion

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Sep 23, 2019 at 12:39 PM Dan Carpenter <dan.carpenter@xxxxxxxxxx> wrote:
>
> In GCC the enum would be a signed int,

That would be broken. You can't fit 0x80000000 in a signed int.

But that's not actually what gcc does.

For gcc, the type of the 'enum' is actually 'long'.

But the type of 'a' is 'unsigned int', and the type of 'b' is 'long'.

Yes, crazy and arguably completely broken, but there you are.

> but in Sparse it is a signed
> long (on my 64 bit system).  That would be fine except the second issue
> is the signed bit isn't expanded correctly because a long -1 should be
> 0xffffffffffffffff and the expr->value is 0xffffffff.

Well, that's even more broken, of course.

sparse makes everything have the same type, but yes, it has corrupted
the value of 'b'.

We used to get this right (well, I'm sure we got other things wrong),
and bisecting shows that it was brokenb by commit 604a148a ("enum: fix
cast_enum_list()").

Luc - I _suspect_ that what happens is that it now does that

                expr->ctype = base_type;

in parse.c, which is correct in the long run, but AT THE TIME it is
parsed, the type hasn't been finalized yet. That's fine - we'll fix it
in-place eventually.

HOWEVER. We also do this:

                if (ctype->bit_size == base_type->bit_size)
                        continue;
                cast_value(expr, base_type, expr, ctype);

and I think it's that 'cast_value()' that gets things wrong somehow.
It probably uses a 'unsigned int' either as the source or the
destination, or something.

Luc?

            Linus



[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux