mysterymath added inline comments.

================
Comment at: clang/docs/ReleaseNotes.rst:43-45
+- The definition of ``USHRT_MAX`` in the freestanding ``<limits.h>`` no longer
+  overflows on AVR (where ``sizeof(unsigned int) == sizeof(unsigned short)``).
+  The type of ``USHRT_MAX`` on AVR is now ``unsigned int`` instead of ``int``,
----------------
aaron.ballman wrote:
> I'd be surprised if this actually has much of a chance to break people. I'd 
> probably put this under a new AVR section under `Target Specific Changes`, 
> WDYT?
SGTM; I was on the fence about this.


================
Comment at: clang/lib/Headers/limits.h:55
 #define UCHAR_MAX (__SCHAR_MAX__*2  +1)
-#define USHRT_MAX (__SHRT_MAX__ *2  +1)
+#if __SHRT_MAX__ * 2U + 1U <= __INT_MAX__
+#define USHRT_MAX (__SHRT_MAX__ * 2 + 1)
----------------
aaron.ballman wrote:
> Rather than do math here, WDYT about using the WIDTH macros? It seems like a 
> more direct comparison:
> ```
> #if __SHRT_WIDTH__ == __INT_WIDTH__
> #endif
> ```
> (This also makes me wonder if we have any targets where we need to do this 
> with `UCHAR_MAX` as well. IIRC, we only support `CHAR_BIT` == 8 and so we're 
> probably fine, but might as well double-check since we're fixing this kind of 
> mistake.)
> Rather than do math here, WDYT about using the WIDTH macros? It seems like a 
> more direct comparison:
Spent a few seconds proving always holds, and it does, so long as you have the 
2's complement ranges. Given that the C standard formalized this in 2x, and 
it's all Clang supports anyway, SGTM.

In Clang's TargetInfo, CharWidth  is hard coded to 8, so there's no way to have 
a uchar that won't fit into int at present. I did add a test for this though in 
the limits.cpp, so if such a target were added to the list to check in the RUN 
lines, it would break.
That being said, it probably *wouldn't* be added, as was the case with AVR; if 
AVR had run under that test, this issue would have been caught even with the 
original version at HEAD.


================
Comment at: clang/lib/Headers/limits.h:55
 #define UCHAR_MAX (__SCHAR_MAX__*2  +1)
-#define USHRT_MAX (__SHRT_MAX__ *2  +1)
+#if __SHRT_MAX__ * 2U + 1U <= __INT_MAX__
+#define USHRT_MAX (__SHRT_MAX__ * 2 + 1)
----------------
mysterymath wrote:
> aaron.ballman wrote:
> > Rather than do math here, WDYT about using the WIDTH macros? It seems like 
> > a more direct comparison:
> > ```
> > #if __SHRT_WIDTH__ == __INT_WIDTH__
> > #endif
> > ```
> > (This also makes me wonder if we have any targets where we need to do this 
> > with `UCHAR_MAX` as well. IIRC, we only support `CHAR_BIT` == 8 and so 
> > we're probably fine, but might as well double-check since we're fixing this 
> > kind of mistake.)
> > Rather than do math here, WDYT about using the WIDTH macros? It seems like 
> > a more direct comparison:
> Spent a few seconds proving always holds, and it does, so long as you have 
> the 2's complement ranges. Given that the C standard formalized this in 2x, 
> and it's all Clang supports anyway, SGTM.
> 
> In Clang's TargetInfo, CharWidth  is hard coded to 8, so there's no way to 
> have a uchar that won't fit into int at present. I did add a test for this 
> though in the limits.cpp, so if such a target were added to the list to check 
> in the RUN lines, it would break.
> That being said, it probably *wouldn't* be added, as was the case with AVR; 
> if AVR had run under that test, this issue would have been caught even with 
> the original version at HEAD.
> Rather than do math here, WDYT about using the WIDTH macros? It seems like a 
> more direct comparison:
> ```
> #if __SHRT_WIDTH__ == __INT_WIDTH__
> #endif
> ```
> (This also makes me wonder if we have any targets where we need to do this 
> with `UCHAR_MAX` as well. IIRC, we only support `CHAR_BIT` == 8 and so we're 
> probably fine, but might as well double-check since we're fixing this kind of 
> mistake.)




================
Comment at: clang/lib/Headers/limits.h:55
 #define UCHAR_MAX (__SCHAR_MAX__*2  +1)
-#define USHRT_MAX (__SHRT_MAX__ *2  +1)
+#define USHRT_MAX (__SHRT_MAX__ * 2U + 1U)
 #define UINT_MAX  (__INT_MAX__  *2U +1U)
----------------
aaron.ballman wrote:
> mysterymath wrote:
> > aaron.ballman wrote:
> > > mysterymath wrote:
> > > > aaron.ballman wrote:
> > > > > It's worth double-checking that this still gives the correct type for 
> > > > > the macro:
> > > > > 
> > > > > C2x 5.2.4.2.1p2: For all unsigned integer types for which <limits.h> 
> > > > > or <stdint.h> define a macro with suffix _WIDTH holding its width N, 
> > > > > there is a macro with suffix _MAX holding the maximal value 2N − 1 
> > > > > that is representable by the type and that has the same type as would 
> > > > > an expression that is an object of the corresponding type converted 
> > > > > according to the integer promotions. ...
> > > > Ah, thanks; it hadn't occurred to me that the type of the expression 
> > > > would be specified in the standard. It could be either `unsigned int` 
> > > > or `int`, depending on the target.
> > > > 
> > > > The most straightforward approach I could think of to produce the right 
> > > > type is:
> > > > 1) Perform the arithmetic in `unsigned int` to produce the right value
> > > > 2) Cast to `unsigned short` to produce the right type
> > > > 3) Directly perform integer promotion using unary plus
> > > > 
> > > > The use of unary plus is a bit odd here, but it seems like the most 
> > > > direct way to express the logic, and the overall expression seems less 
> > > > fragile than the `#if` alternative. I've added a comment to explain 
> > > > this as well.
> > > Now the trouble is with the cast operation, because that runs afoul of 
> > > 5.2.4.2.1p1: The values given below shall be replaced by constant 
> > > expressions suitable for use in conditional expression inclusion 
> > > preprocessing directives. ...
> > > 
> > > https://godbolt.org/z/K9cs66sdK
> > > 
> > > I'm almost wondering if the most direct solution is for `__SHRT_MAX__` to 
> > > be generated with or without the `U` suffix depending on target.
> > > 
> > > We should probably use this as an opportunity to add more exhaustive 
> > > testing for all the _MIN and _MAX macros to ensure the type properties 
> > > hold. I was playing around with something like this: 
> > > https://godbolt.org/z/o7KjY3asW
> > > Now the trouble is with the cast operation, because that runs afoul of 
> > > 5.2.4.2.1p1: The values given below shall be replaced by constant 
> > > expressions suitable for use in conditional expression inclusion 
> > > preprocessing directives. ...
> > > 
> > > https://godbolt.org/z/K9cs66sdK
> > > 
> > Sigh, it appears my standards-fu is not strong. I'm rather surprised to 
> > find that you can't cast to an integer type in `#if`; 6.10.1.6 claim they 
> > take a `constant-expression`, evaluated according to 6.6. But I can't find 
> > anything in 6.6 that seems to exclude cast operators. The definition of 
> > integer constant expressions even specifically calls out casts to integer 
> > types, although it doesn't specifically say in 6.10.1.6 that it takes an 
> > integer constant expression.
> > Would you happen to know off-hand what my mistake is?
> > 
> > I think the `#if` version I had originally isn't subject to this; I'll 
> > switch back to that. 
> > 
> > > I'm almost wondering if the most direct solution is for `__SHRT_MAX__` to 
> > > be generated with or without the `U` suffix depending on target.
> > Seems like that wouldn't work for the more straightforward case of `#define 
> > SHRT_MAX __SHRT_MAX__`; the type of this must always be int, since SHRT_MAX 
> > is always representable in int, even on 16-bit targets.
> >  
> > > We should probably use this as an opportunity to add more exhaustive 
> > > testing for all the _MIN and _MAX macros to ensure the type properties 
> > > hold. I was playing around with something like this: 
> > > https://godbolt.org/z/o7KjY3asW
> > Agree; I think a slight modification to the type test macros I added to the 
> > limits.cpp test can accomodate this. Seems like it would also be a good 
> > idea to verify 5.2.4.2.1p1 directly by using the values in the preprocessor.
> > Sigh, it appears my standards-fu is not strong. 
> 
> No worries, this is what code review is intended to catch! :-)
> 
> > I'm rather surprised to find that you can't cast to an integer type in #if; 
> > 6.10.1.6 claim they take a constant-expression, evaluated according to 6.6. 
> > But I can't find anything in 6.6 that seems to exclude cast operators. The 
> > definition of integer constant expressions even specifically calls out 
> > casts to integer types, although it doesn't specifically say in 6.10.1.6 
> > that it takes an integer constant expression.
> > Would you happen to know off-hand what my mistake is?
> 
> The preprocessor has no notion of types, just numbers, identifiers, and 
> punctuation. Any identifier that isn't known to the preprocessor is replaced 
> by `0`, which is what allows code like this to compile: 
> https://godbolt.org/z/P3rzG8sxo
> 
> So your previous macro would expand to `(+(0 0)(0x7FFF * 2U + 1U))` and the 
> preprocessor would get baffled.
> 
> > Seems like that wouldn't work for the more straightforward case of #define 
> > SHRT_MAX __SHRT_MAX__; the type of this must always be int, since SHRT_MAX 
> > is always representable in int, even on 16-bit targets.
> 
> Good point!
> The preprocessor has no notion of types, just numbers, identifiers, and 
> punctuation. Any identifier that isn't known to the preprocessor is replaced 
> by `0`, which is what allows code like this to compile: 
> https://godbolt.org/z/P3rzG8sxo
> 
> So your previous macro would expand to `(+(0 0)(0x7FFF * 2U + 1U))` and the 
> preprocessor would get baffled.
Ah, the replacement by zero was what got me. It sounds from the wording in the 
standard that it's technically legal to have a cast in a constant expression in 
the preprocessor, but there's no way to actually *express* such a cast, since 
all the terms in it would be replaced by zeroes. Guess it saved them having to 
define a "preprocessor constant expression" notion.



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D144218

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to