[PATCH] D144218: [Clang] [AVR] Fix USHRT_MAX for 16-bit int.
Daniel Thornburgh via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 22 15:40:05 PST 2023
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
-----------------------------------------
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D144218.499659.patch
Type: text/x-patch
Size: 2437 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230222/8537455a/attachment-0001.bin>
More information about the cfe-commits
mailing list