[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