[libc-commits] [PATCH] D140350: [libc][NFC] make atoi undefined cases match std

Michael Jones via Phabricator via libc-commits libc-commits at lists.llvm.org
Tue Dec 20 10:21:10 PST 2022


michaelrj updated this revision to Diff 484313.
michaelrj marked 2 inline comments as done.
michaelrj added a comment.

address comments and rebase before landing


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140350

Files:
  libc/src/stdlib/atoi.cpp
  libc/test/src/stdlib/AtoiTest.h


Index: libc/test/src/stdlib/AtoiTest.h
===================================================================
--- libc/test/src/stdlib/AtoiTest.h
+++ libc/test/src/stdlib/AtoiTest.h
@@ -6,10 +6,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "src/__support/CPP/type_traits.h"
 #include "utils/UnitTest/Test.h"
 
 #include <limits.h>
 
+using __llvm_libc::cpp::is_same_v;
+
 template <typename ReturnT> struct AtoTest : public __llvm_libc::testing::Test {
   using FunctionT = ReturnT (*)(const char *);
 
@@ -54,6 +57,26 @@
       const char *smallest_long_long = "-9223372036854775808";
       ASSERT_EQ(func(smallest_long_long), static_cast<ReturnT>(LLONG_MIN));
     }
+
+    // If this is atoi and the size of int is less than the size of long, then
+    // we parse as long and cast to int to match existing behavior. This only
+    // matters for cases where the result would be outside of the int range, and
+    // those cases are undefined, so we can choose whatever output value we
+    // want. In this case we have chosen to cast since that matches existing
+    // implementations and makes differential fuzzing easier, but no user should
+    // rely on this behavior.
+    if constexpr (is_same_v<ReturnT, int> && sizeof(ReturnT) < sizeof(long)) {
+
+      static_assert(sizeof(int) == 4);
+
+      const char *bigger_than_biggest_int = "2147483649";
+      ASSERT_EQ(func(bigger_than_biggest_int),
+                static_cast<ReturnT>(2147483649));
+
+      const char *smaller_than_smallest_int = "-2147483649";
+      ASSERT_EQ(func(smaller_than_smallest_int),
+                static_cast<ReturnT>(-2147483649));
+    }
   }
 
   void nonBaseTenWholeNumbers(FunctionT func) {
Index: libc/src/stdlib/atoi.cpp
===================================================================
--- libc/src/stdlib/atoi.cpp
+++ libc/src/stdlib/atoi.cpp
@@ -13,11 +13,13 @@
 namespace __llvm_libc {
 
 LLVM_LIBC_FUNCTION(int, atoi, (const char *str)) {
-  auto result = internal::strtointeger<int>(str, 10);
+  // This is done because the standard specifies that atoi is identical to
+  // (int)(strtol).
+  auto result = internal::strtointeger<long>(str, 10);
   if (result.has_error())
     errno = result.error;
 
-  return result;
+  return static_cast<int>(result);
 }
 
 } // namespace __llvm_libc


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D140350.484313.patch
Type: text/x-patch
Size: 2357 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libc-commits/attachments/20221220/d7687f59/attachment.bin>


More information about the libc-commits mailing list