[cfe-commits] [PATCH] Improved handling of 128-bit integer literals
Stephen Canon
scanon at apple.com
Thu Nov 29 16:27:31 PST 2012
> Index: lib/Sema/SemaExpr.cpp
> ===================================================================
> --- lib/Sema/SemaExpr.cpp (revision 168447)
> +++ lib/Sema/SemaExpr.cpp (working copy)
> [...]
> + // Microsoft literals simply *are* the specified type, regardless of
> + // whether the value fits into it or not, or whether they are hex or
> + // decimal or octal.
> + if (Literal.isLongLong) {
> + Width = Context.getTargetInfo().getLongLongWidth();
> + Ty = Literal.isUnsigned ? Context.UnsignedLongLongTy :
> + Context.LongLongTy;
> + } else if (Literal.isLong) {
> + Width = Context.getTargetInfo().getLongWidth();
> + Ty = Literal.isUnsigned ? Context.UnsignedLongTy : Context.LongTy;
> + } else {
> + Width = Context.getTargetInfo().getIntWidth();
> + Ty = Literal.isUnsigned ? Context.UnsignedIntTy : Context.IntTy;
> }
>
> Hmm, it looks incorrect to use isLong here instead of checking microsoftWidth. In particular, if I use -fms-extensions on Linux, this static_assert fails:
>
> static_assert(sizeof(0i32) == 4, "");
>
> ... because 'long' is a 64-bit type on my target. (We also incorrectly use 'int' for i16 and i8.) We should presumably use the smallest integer type which is at least N bits wide. I'm OK with this being dealt with in a separate patch, since it's not a regression.
I'll take a look at these in another patch.
> + if (ResultVal.getActiveBits() > (Literal.isUnsigned ?
> + Literal.microsoftWidth :
> + Literal.microsoftWidth - 1)) {
> + Diag(Tok.getLocation(), diag::warn_integer_too_large);
> + // APInt asserts on NOP-truncations, so we need to be a little bit
> + // carefull; otherwise we would crash when the literal is signed and
> + // microsoftWidth == Width.
> + if (Literal.microsoftWidth < Width)
> + ResultVal = ResultVal.trunc(Literal.microsoftWidth);
>
> This can be simplified somewhat by passing Literal.microsoftWidth instead of 64 when constructing ResultVal (you'd still need to check for the high bit being set for a signed literal).
Sounds good.
> }
> +
> + // Unlike in the non-MS-literal case, we may have already truncated the
> + // APInt to be smaller than the final literal, so we may need to adjust
> + // the size in either direciton here; use sextOrTrunc instead of trunc.
> + if (ResultVal.getBitWidth() != Width)
> + ResultVal = ResultVal.sextOrTrunc(Width);
>
> You should zext if the literal is unsigned (maybe make ResultVal an APSInt, and use extOrTrunc). For instance, 0x18000Ui16 will currently first be truncated to 0x8000 (with a warning), then sign extended to 0x80000000, rather than producing the desired value 0x00008000.
Yep, I'll fix this.
> + // Checking for 64-bit pointers is perhaps not the correct way to detect
> + // i128 support, but it seems to be what is done elsewhere.
> + if (PP.getTargetInfo().getPointerWidth(0) >= 64) {
>
> TargetInfo now has a hasInt128Type().
Great, that's very helpful.
- Steve
More information about the cfe-commits
mailing list