mysterymath updated this revision to Diff 499659. mysterymath added a comment.
Corrected type of USHRT_MAX. Added tests and release notes. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D144218/new/ https://reviews.llvm.org/D144218 Files: clang/docs/ReleaseNotes.rst clang/lib/Headers/limits.h clang/test/Headers/limits.cpp Index: clang/test/Headers/limits.cpp =================================================================== --- clang/test/Headers/limits.cpp +++ clang/test/Headers/limits.cpp @@ -3,6 +3,10 @@ // RUN: %clang_cc1 -std=c++11 -ffreestanding -fsyntax-only -verify %s // RUN: %clang_cc1 -std=c17 -ffreestanding -fsyntax-only -verify -x c %s // RUN: %clang_cc1 -std=c2x -ffreestanding -fsyntax-only -verify -x c %s + +// Specifically test 16-bit int platforms. +// RUN: %clang_cc1 -triple=avr -ffreestanding -fsyntax-only -verify -x c %s + // expected-no-diagnostics #include <limits.h> @@ -24,6 +28,16 @@ _Static_assert(UCHAR_MAX == (unsigned char)~0ULL, ""); _Static_assert(USHRT_MAX == (unsigned short)~0ULL, ""); + +#if __cplusplus +#define EXPR_TYPE_IS(EXPR, TYP) __is_same(__typeof(EXPR), TYP) +#else +#define EXPR_TYPE_IS(EXPR, TYP) _Generic(EXPR, TYP: 1, default: 0) +#endif +_Static_assert(USHRT_MAX <= INT_MAX ? + EXPR_TYPE_IS(USHRT_MAX, int) : + EXPR_TYPE_IS(USHRT_MAX, unsigned int), ""); + _Static_assert(UINT_MAX == (unsigned int)~0ULL, ""); _Static_assert(ULONG_MAX == (unsigned long)~0ULL, ""); Index: clang/lib/Headers/limits.h =================================================================== --- clang/lib/Headers/limits.h +++ clang/lib/Headers/limits.h @@ -52,7 +52,10 @@ #define LONG_MIN (-__LONG_MAX__ -1L) #define UCHAR_MAX (__SCHAR_MAX__*2 +1) -#define USHRT_MAX (__SHRT_MAX__ *2 +1) +/* This isn't safe to compute in type int on 16-bit int platforms, so compute it + * in unsigned int, cast to unsigned short, and perform the regular integer + * promotion via unary plus. */ +#define USHRT_MAX (+(unsigned short)(__SHRT_MAX__ * 2U + 1U)) #define UINT_MAX (__INT_MAX__ *2U +1U) #define ULONG_MAX (__LONG_MAX__ *2UL+1UL) Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -40,6 +40,10 @@ C/C++ Language Potentially Breaking Changes ------------------------------------------- +- 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``, + as required by the C standard. C++ Specific Potentially Breaking Changes -----------------------------------------
Index: clang/test/Headers/limits.cpp =================================================================== --- clang/test/Headers/limits.cpp +++ clang/test/Headers/limits.cpp @@ -3,6 +3,10 @@ // RUN: %clang_cc1 -std=c++11 -ffreestanding -fsyntax-only -verify %s // RUN: %clang_cc1 -std=c17 -ffreestanding -fsyntax-only -verify -x c %s // RUN: %clang_cc1 -std=c2x -ffreestanding -fsyntax-only -verify -x c %s + +// Specifically test 16-bit int platforms. +// RUN: %clang_cc1 -triple=avr -ffreestanding -fsyntax-only -verify -x c %s + // expected-no-diagnostics #include <limits.h> @@ -24,6 +28,16 @@ _Static_assert(UCHAR_MAX == (unsigned char)~0ULL, ""); _Static_assert(USHRT_MAX == (unsigned short)~0ULL, ""); + +#if __cplusplus +#define EXPR_TYPE_IS(EXPR, TYP) __is_same(__typeof(EXPR), TYP) +#else +#define EXPR_TYPE_IS(EXPR, TYP) _Generic(EXPR, TYP: 1, default: 0) +#endif +_Static_assert(USHRT_MAX <= INT_MAX ? + EXPR_TYPE_IS(USHRT_MAX, int) : + EXPR_TYPE_IS(USHRT_MAX, unsigned int), ""); + _Static_assert(UINT_MAX == (unsigned int)~0ULL, ""); _Static_assert(ULONG_MAX == (unsigned long)~0ULL, ""); Index: clang/lib/Headers/limits.h =================================================================== --- clang/lib/Headers/limits.h +++ clang/lib/Headers/limits.h @@ -52,7 +52,10 @@ #define LONG_MIN (-__LONG_MAX__ -1L) #define UCHAR_MAX (__SCHAR_MAX__*2 +1) -#define USHRT_MAX (__SHRT_MAX__ *2 +1) +/* This isn't safe to compute in type int on 16-bit int platforms, so compute it + * in unsigned int, cast to unsigned short, and perform the regular integer + * promotion via unary plus. */ +#define USHRT_MAX (+(unsigned short)(__SHRT_MAX__ * 2U + 1U)) #define UINT_MAX (__INT_MAX__ *2U +1U) #define ULONG_MAX (__LONG_MAX__ *2UL+1UL) Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -40,6 +40,10 @@ C/C++ Language Potentially Breaking Changes ------------------------------------------- +- 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``, + as required by the C standard. C++ Specific Potentially Breaking Changes -----------------------------------------
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits