Define strnlen when it is not in libc

Chi-Hua Chen via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 29 19:36:48 PST 2016


Attached is the updated patch.

On Mon, Nov 28, 2016 at 9:16 PM, Hubert Tong
<hubert.reinterpretcast at gmail.com> wrote:
> This implementation of strnlen reads one more byte than is allowed by the
> specification at
> http://pubs.opengroup.org/onlinepubs/9699919799/functions/strlen.html.
>
> -- HT
>
> On Thu, Nov 24, 2016 at 2:06 PM, Chi-Hua Chen via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
>>
>> Some older platforms, e.g. Mac 10.6.8, do not have strnlen. Define one
>> in Support when necessary.
>>
>> Cc-ing dexonsmith because the commit below is the first one using strnlen
>> ---
>> commit 839cd13b65d802f06276ff88d234419c38a44199
>> Author: Duncan P. N. Exon Smith <dexonsmith at apple.com>
>> Date:   Sun Feb 21 00:14:36 2016 +0000
>>
>>     Lex: Never overflow the file in HeaderMap::lookupFilename()
>> ---
>> See https://llvm.org/bugs/show_bug.cgi?id=27714
>>
>> - Chi-Hua Chen
>>
>> p.s. This is the first time I submit to llvm-commits. I've read the
>> Developer Policy but please let me know if I am not doing it right
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>
-------------- next part --------------
Index: clang/lib/Lex/HeaderMap.cpp
===================================================================
--- clang/lib/Lex/HeaderMap.cpp	(revision 288226)
+++ clang/lib/Lex/HeaderMap.cpp	(working copy)
@@ -22,6 +22,7 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/SwapByteOrder.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/string_compat.h"
 #include <cstring>
 #include <memory>
 using namespace clang;
Index: llvm/cmake/config-ix.cmake
===================================================================
--- llvm/cmake/config-ix.cmake	(revision 288226)
+++ llvm/cmake/config-ix.cmake	(working copy)
@@ -182,6 +182,7 @@
 check_symbol_exists(strerror string.h HAVE_STRERROR)
 check_symbol_exists(strerror_r string.h HAVE_STRERROR_R)
 check_symbol_exists(strerror_s string.h HAVE_DECL_STRERROR_S)
+check_symbol_exists(strnlen string.h HAVE_STRNLEN)
 check_symbol_exists(setenv stdlib.h HAVE_SETENV)
 if( PURE_WINDOWS )
   check_symbol_exists(_chsize_s io.h HAVE__CHSIZE_S)
Index: llvm/include/llvm/Config/config.h.cmake
===================================================================
--- llvm/include/llvm/Config/config.h.cmake	(revision 288226)
+++ llvm/include/llvm/Config/config.h.cmake	(working copy)
@@ -201,6 +201,9 @@
 /* Define to 1 if you have the `strtoll' function. */
 #cmakedefine HAVE_STRTOLL ${HAVE_STRTOLL}
 
+/* Define to 1 if you have the `strnlen' function. */
+#cmakedefine HAVE_STRNLEN ${HAVE_STRNLEN}
+
 /* Define to 1 if you have the `sysconf' function. */
 #cmakedefine HAVE_SYSCONF ${HAVE_SYSCONF}
 
Index: llvm/include/llvm/Support/string_compat.h
===================================================================
--- llvm/include/llvm/Support/string_compat.h	(revision 0)
+++ llvm/include/llvm/Support/string_compat.h	(working copy)
@@ -0,0 +1,20 @@
+#ifndef LLVM_SUPPORT_STRING_COMPAT_H
+#define LLVM_SUPPORT_STRING_COMPAT_H
+
+#include <stdlib.h>
+
+#include "llvm/Config/llvm-config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !HAVE_STRNLEN
+size_t strnlen(const char *s, size_t maxlen);
+#endif /* LLVM_HAS_STRNLEN */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LLVM_SUPPORT_STRING_COMPAT_H */
Index: llvm/lib/ObjectYAML/MachOYAML.cpp
===================================================================
--- llvm/lib/ObjectYAML/MachOYAML.cpp	(revision 288226)
+++ llvm/lib/ObjectYAML/MachOYAML.cpp	(working copy)
@@ -15,6 +15,7 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/MachO.h"
+#include "llvm/Support/string_compat.h"
 
 #include <string.h> // For memcpy, memset and strnlen.
 
Index: llvm/lib/Support/CMakeLists.txt
===================================================================
--- llvm/lib/Support/CMakeLists.txt	(revision 288226)
+++ llvm/lib/Support/CMakeLists.txt	(working copy)
@@ -84,6 +84,7 @@
   SourceMgr.cpp
   SpecialCaseList.cpp
   Statistic.cpp
+  strnlen.c
   StringExtras.cpp
   StringMap.cpp
   StringPool.cpp
Index: llvm/lib/Support/strnlen.c
===================================================================
--- llvm/lib/Support/strnlen.c	(revision 0)
+++ llvm/lib/Support/strnlen.c	(working copy)
@@ -0,0 +1,10 @@
+#include "llvm/Support/string_compat.h"
+
+#if !HAVE_STRNLEN
+size_t strnlen(const char *s, size_t maxlen) {
+  size_t rv = 0;
+  while (maxlen-- > 0 && *s++)
+    ++rv;
+  return rv;
+}
+#endif
Index: llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
===================================================================
--- llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp	(revision 288226)
+++ llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp	(working copy)
@@ -28,6 +28,7 @@
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
 #include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
 #include "llvm/Object/COFF.h"
+#include "llvm/Support/string_compat.h"
 
 #include <unordered_map>
 
Index: llvm/tools/obj2yaml/macho2yaml.cpp
===================================================================
--- llvm/tools/obj2yaml/macho2yaml.cpp	(revision 288226)
+++ llvm/tools/obj2yaml/macho2yaml.cpp	(working copy)
@@ -13,6 +13,7 @@
 #include "llvm/ObjectYAML/ObjectYAML.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/LEB128.h"
+#include "llvm/Support/string_compat.h"
 
 #include <string.h> // for memcpy
 
Index: llvm/unittests/Support/CMakeLists.txt
===================================================================
--- llvm/unittests/Support/CMakeLists.txt	(revision 288226)
+++ llvm/unittests/Support/CMakeLists.txt	(working copy)
@@ -40,6 +40,7 @@
   SourceMgrTest.cpp
   SpecialCaseListTest.cpp
   StringPool.cpp
+  StrnlenTest.cpp
   SwapByteOrderTest.cpp
   TargetParserTest.cpp
   Threading.cpp
Index: llvm/unittests/Support/StrnlenTest.cpp
===================================================================
--- llvm/unittests/Support/StrnlenTest.cpp	(revision 0)
+++ llvm/unittests/Support/StrnlenTest.cpp	(working copy)
@@ -0,0 +1,22 @@
+#include "llvm/Support/string_compat.h"
+#include "gtest/gtest.h"
+
+#if !HAVE_STRNLEN
+using namespace llvm;
+namespace {
+
+class StrnlenTest : public ::testing::Test {};
+
+TEST_F(StrnlenTest, Basics) {
+  EXPECT_EQ(0u, strnlen("", 0));
+  EXPECT_EQ(0u, strnlen("", 1));
+  EXPECT_EQ(0u, strnlen("a", 0));
+  EXPECT_EQ(1u, strnlen("a", 1));
+  EXPECT_EQ(1u, strnlen("a", 2));
+  EXPECT_EQ(1u, strnlen("aa", 1));
+  EXPECT_EQ(2u, strnlen("aa", 2));
+  EXPECT_EQ(2u, strnlen("aabbcc", 2));
+  EXPECT_EQ(0u, strnlen("aabbcc", 0));
+}
+}
+#endif


More information about the llvm-commits mailing list