From 1fcfd30fae76fb1d30906a65c670cce32fd5cf15 Mon Sep 17 00:00:00 2001 From: Paula Toth Date: Fri, 3 Apr 2020 14:47:15 -0700 Subject: [PATCH] [libc] Add strlen implementation. Summary: This should fix the call to a non internal libc function. Reviewers: sivachandra, abrachet Reviewed By: sivachandra Subscribers: xbolva00, mgorny, MaskRay, tschuett, libc-commits Tags: #libc-project Differential Revision: https://reviews.llvm.org/D77279 --- libc/fuzzing/string/CMakeLists.txt | 1 + libc/src/string/CMakeLists.txt | 12 ++++++++++++ libc/src/string/strcat.cpp | 7 +++---- libc/src/string/strcpy.cpp | 4 +++- libc/src/string/strlen.cpp | 24 ++++++++++++++++++++++++ libc/src/string/strlen.h | 20 ++++++++++++++++++++ libc/test/src/string/CMakeLists.txt | 12 ++++++++++++ libc/test/src/string/strlen_test.cpp | 24 ++++++++++++++++++++++++ 8 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 libc/src/string/strlen.cpp create mode 100644 libc/src/string/strlen.h create mode 100644 libc/test/src/string/strlen_test.cpp diff --git a/libc/fuzzing/string/CMakeLists.txt b/libc/fuzzing/string/CMakeLists.txt index 0482b961e576..c28c0e4dd0d3 100644 --- a/libc/fuzzing/string/CMakeLists.txt +++ b/libc/fuzzing/string/CMakeLists.txt @@ -4,4 +4,5 @@ add_libc_fuzzer( strcpy_fuzz.cpp DEPENDS strcpy + strlen ) diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt index 729ccaaa2b20..abe978767989 100644 --- a/libc/src/string/CMakeLists.txt +++ b/libc/src/string/CMakeLists.txt @@ -9,6 +9,7 @@ add_entrypoint_object( DEPENDS strcpy string_h + strlen ) add_entrypoint_object( @@ -19,6 +20,17 @@ add_entrypoint_object( strcpy.h DEPENDS string_h + strlen +) + +add_entrypoint_object( + strlen + SRCS + strlen.cpp + HDRS + strlen.h + DEPENDS + string_h ) # ------------------------------------------------------------------------------ diff --git a/libc/src/string/strcat.cpp b/libc/src/string/strcat.cpp index 366b1854e601..4fc10da3453b 100644 --- a/libc/src/string/strcat.cpp +++ b/libc/src/string/strcat.cpp @@ -7,16 +7,15 @@ //===----------------------------------------------------------------------===// #include "src/string/strcat.h" +#include "src/string/strcpy.h" +#include "src/string/strlen.h" #include "src/__support/common.h" -#include "src/string/strcpy.h" namespace __llvm_libc { char *LLVM_LIBC_ENTRYPOINT(strcat)(char *dest, const char *src) { - // We do not yet have an implementaion of strlen in so we will use strlen - // from another libc. - __llvm_libc::strcpy(dest + ::strlen(dest), src); + __llvm_libc::strcpy(dest + __llvm_libc::strlen(dest), src); return dest; } diff --git a/libc/src/string/strcpy.cpp b/libc/src/string/strcpy.cpp index 22fe4ccffa40..46cdb1c87314 100644 --- a/libc/src/string/strcpy.cpp +++ b/libc/src/string/strcpy.cpp @@ -7,13 +7,15 @@ //===----------------------------------------------------------------------===// #include "src/string/strcpy.h" +#include "src/string/strlen.h" #include "src/__support/common.h" namespace __llvm_libc { char *LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) { - return reinterpret_cast(::memcpy(dest, src, ::strlen(src) + 1)); + return reinterpret_cast( + ::memcpy(dest, src, __llvm_libc::strlen(src) + 1)); } } // namespace __llvm_libc diff --git a/libc/src/string/strlen.cpp b/libc/src/string/strlen.cpp new file mode 100644 index 000000000000..3aeafc37bcc8 --- /dev/null +++ b/libc/src/string/strlen.cpp @@ -0,0 +1,24 @@ +//===-------------------- Implementation of strlen ------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/string/strlen.h" + +#include "src/__support/common.h" + +namespace __llvm_libc { + +// TODO: investigate the performance of this function. +// There might be potential for compiler optmization. +size_t LLVM_LIBC_ENTRYPOINT(strlen)(const char *src) { + const char *end = src; + while (*end != '\0') + ++end; + return end - src; +} + +} // namespace __llvm_libc diff --git a/libc/src/string/strlen.h b/libc/src/string/strlen.h new file mode 100644 index 000000000000..32f1d9a8ba94 --- /dev/null +++ b/libc/src/string/strlen.h @@ -0,0 +1,20 @@ +//===----------------- Implementation header for strlen -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_STRING_STRLEN_H +#define LLVM_LIBC_SRC_STRING_STRLEN_H + +#include "include/string.h" + +namespace __llvm_libc { + +size_t strlen(const char *src); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STRING_STRLEN_H diff --git a/libc/test/src/string/CMakeLists.txt b/libc/test/src/string/CMakeLists.txt index 43536e96d552..cb134515081b 100644 --- a/libc/test/src/string/CMakeLists.txt +++ b/libc/test/src/string/CMakeLists.txt @@ -11,6 +11,7 @@ add_libc_unittest( DEPENDS strcat strcpy + strlen ) add_libc_unittest( @@ -21,6 +22,17 @@ add_libc_unittest( strcpy_test.cpp DEPENDS strcpy + strlen +) + +add_libc_unittest( + strlen_test + SUITE + libc_string_unittests + SRCS + strlen_test.cpp + DEPENDS + strlen ) # Tests all implementations of memcpy that can run on the host. diff --git a/libc/test/src/string/strlen_test.cpp b/libc/test/src/string/strlen_test.cpp new file mode 100644 index 000000000000..f2df81dbf697 --- /dev/null +++ b/libc/test/src/string/strlen_test.cpp @@ -0,0 +1,24 @@ +//===----------------------- Unittests for strlen -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/string/strlen.h" +#include "utils/UnitTest/Test.h" + +TEST(StrLenTest, EmptyString) { + const char *empty = ""; + + size_t result = __llvm_libc::strlen(empty); + ASSERT_EQ((size_t)0, result); +} + +TEST(StrLenTest, AnyString) { + const char *any = "Hello World!"; + + size_t result = __llvm_libc::strlen(any); + ASSERT_EQ((size_t)12, result); +}