[PATCH] D116203: [clang] adds unary type transformations as compiler built-ins

Richard Smith - zygoloid via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 14 14:07:13 PDT 2022


rsmith added inline comments.


================
Comment at: clang/lib/Sema/SemaType.cpp:9265-9266
+          ? Context.getBitIntType(!IsMakeSigned, Context.getIntWidth(BaseType))
+          : Context.getIntTypeForBitwidth(Context.getIntWidth(BaseType),
+                                          IsMakeSigned);
+  Qualifiers Quals = Underlying.getQualifiers();
----------------
rsmith wrote:
> cjdb wrote:
> > rsmith wrote:
> > > This is wrong: if, say, `int` and `long` are the same bit-width, this will give the same type for `__make_unsigned(int)` and `__make_unsigned(long)`, where they are required to produce `unsigned int` and `unsigned long` respectively.
> > > 
> > > Please look at `Context.getCorrespondingSignedType` and `Context.getCorrespondingUnsignedType` to see how to do this properly; you may be able to call those functions directly in some cases, but be careful about the cases where we're required to return the lowest-rank int type of the given size. Note that `getIntTypeForBitwidth` does *not* do that; rather, it produces the *preferred* type of the given width, and for WebAssembly and AVR it produces something other than the lowest-rank type in practice in some cases.
> > This makes me very happy.
> The comment on this producing the wrong underlying type for enums in some cases doesn't seem to be addressed. You need to produce the lowest-rank type of the given size, which is not what `getIntTypeForBitwidth` does.
Specifically, the rule you need to implement for enums is that the resulting type "names the [un]signed integer type with smallest rank (6.8.5) for which sizeof(T) == sizeof(type)". So the first of `[un]signed char`, `[un]signed short`, `[un]signed int`, `[un]signed long`, `[un]signed long long` that is the same size as the enum, and if none of those work then an extended integer type.

For example, if `int` and `long` are the same size, then given `enum E : long {};`, `__make_unsigned(E)` is required to produce `unsigned int`, not `unsigned long`. This is not what `getIntTypeForBitwidth` does in general; rather, it answers the target-specific question of "which integer type would you like to be used for an integer that is N bits wide?".


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116203/new/

https://reviews.llvm.org/D116203



More information about the cfe-commits mailing list