public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Leif Lindholm <leif.lindholm@linaro.org>
To: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>, edk2-devel@lists.01.org
Subject: Re: [PATCH] EmbeddedPkg/GdbSerialLib: avoid left shift of negative quantity
Date: Tue, 19 Jun 2018 14:06:48 +0100	[thread overview]
Message-ID: <20180619130648.z3vbxxwewf5ciq5o@bivouac.eciton.net> (raw)
In-Reply-To: <6e536d26-a1bb-52f2-ceca-8b39e35fe5ce@redhat.com>

On Tue, Jun 19, 2018 at 02:51:41PM +0200, Laszlo Ersek wrote:
> On 06/19/18 11:54, Leif Lindholm wrote:
> > On Tue, Jun 19, 2018 at 12:51:49AM +0200, Laszlo Ersek wrote:
> >> On 06/18/18 23:57, Leif Lindholm wrote:
> >>> On Mon, Jun 18, 2018 at 10:49:18PM +0200, Ard Biesheuvel wrote:
> >>>> Clang complains about left shifting a negative value being undefined.
> >>>
> >>> As well it should.
> >>>
> >>>>   EmbeddedPkg/Library/GdbSerialLib/GdbSerialLib.c:151:30:
> >>>>   error: shifting a negative signed value is undefined [-Werror,-Wshift-negative-value]
> >>>>   OutputData = (UINT8)((~DLAB<<7)|((BreakSet<<6)|((Parity<<3)|((StopBits<<2)| Data))));
> >>>>
> >>>> Redefine all bit pattern constants as unsigned to work around this.
> >>>
> >>> So, I'm totally OK with this and
> >>> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
> >>> but ...
> >>> would it be worth fixing up BIT0-31 in Base.h and use those?
> >>
> >> If we started with the BITxx macros now, I'd agree. Given the current
> >> tree, I don't :) I've made an argument against the suggestion earlier:
> >>
> >>   UINT64 Value64;
> >>
> >>   Value64 = ~0x1;
> >>   Value64 = ~0x1U;
> >>
> >> The two assignments produce different results.
> >>
> >> In the first case, the integer constant 0x1 has type "int". Our C
> >> language implementation uses, for type "int", two's complement
> >> representation, 1 sign bit, 31 value bits, and no padding bits. So after
> >> the bitwise complement, we get 0x1111_1111_1111_1110, also with type
> >> int, and with value (-2). Taking UINT64 for "unsigned long int" or
> >> "unsigned long long int", after the conversion implied by the assignment
> >> we get ((UINT64_MAX + 1) + (-2)), aka (UINT64_MAX - 1).
> > 
> > Err, if by UINT64_MAX + 1 you mean 0,
> 
> No, I don't.
> 
> > as a way of introducing the
> > second part, I'm with you. Otherwise I think I need to go back to
> > school.
> 
> I really meant (UINT64_MAX + 1) as the mathematical integer
> 18,446,744,073,709,551,616; without the modular wrap-around that occurs
> in C. The modular wrap-around of C is defined in terms of the
> mathematical values. This is how the ISO C99 standard defines the behavior:
> 
> ------
> 6.3.1.3 Signed and unsigned integers
> 
> 1 When a value with integer type is converted to another integer type
>   other than _Bool, if the value can be represented by the new type, it
>   is unchanged.
> 
> 2 Otherwise, if the new type is unsigned, the value is converted by
>   repeatedly adding or subtracting one more than the maximum value that
>   can be represented in the new type until the value is in the range of
>   the new type. [footnote 49]

So for negative add, for positive subtract? I find the language in the
spec is indicative of the people who write it. And those people spend
a lot of time working on compiler optimisations.

> 3 Otherwise, the new type is signed and the value cannot be represented
>   in it; either the result is implementation-defined or an
>   implementation-defined signal is raised.

*twitch*

> [footnote 49] The rules describe arithmetic on the mathematical value,
> not the value of a given type of expression.
> ------
> 
> Therefore we really have (18,446,744,073,709,551,616 + (-2)) in the
> above reasoning.

Blimey. Live and learn.
Thanks for that - at least the period in school was shorter than I feared.

> >> In the second case, the constant 0x1U has type "unsigned int". After the
> >> bitwise complement, we get (UINT32_MAX - 1), also of type "unsigned
> >> int". Taking UINT64 for "unsigned long int" or "unsigned long long int",
> >> after the conversion implied by assignment we get the exact same value,
> >> (UINT32_MAX - 1).
> > 
> > But these examples make it look like the differences are an
> > unobservable internal side effect. That's not the case.
> 
> Hm, sorry, I don't understand. My point was that the difference was
> extremely observable, because in the first assignment, we end up with
> value 18,446,744,073,709,551,614; in the second, we end up with
> 4,294,967,294.
> 
> Perhaps my expression "exact same value" was misleading.

Yes, that threw me.
Combined with your detestation for sign-extension (which does
help describe the situation without going full spec).

> There I
> referred to 6.3.1.3p1, which I've now quoted above as well -- I meant
> that converting 4,294,967,294 from "unsigned int" to either of "unsigned
> long int" or "unsigned long long int" didn't change the value.

Understood. Thanks a lot!

/
    Leif


      reply	other threads:[~2018-06-19 13:06 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-18 20:49 [PATCH] EmbeddedPkg/GdbSerialLib: avoid left shift of negative quantity Ard Biesheuvel
2018-06-18 21:57 ` Leif Lindholm
2018-06-18 22:07   ` Ard Biesheuvel
2018-06-18 22:51   ` Laszlo Ersek
2018-06-19  6:37     ` Ard Biesheuvel
2018-06-19  9:54     ` Leif Lindholm
2018-06-19 12:51       ` Laszlo Ersek
2018-06-19 13:06         ` Leif Lindholm [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180619130648.z3vbxxwewf5ciq5o@bivouac.eciton.net \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox