Skip to content

[libc] Independent strcat/strncat/stpcpy #142643

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 12, 2025

Conversation

michaelrj-google
Copy link
Contributor

@michaelrj-google michaelrj-google commented Jun 3, 2025

The previous implementations called other entrypoints. This patch fixes
strcat, strncat, and stpcpy to be properly independent.

@llvmbot llvmbot added the libc label Jun 3, 2025
@michaelrj-google michaelrj-google requested a review from lntue June 3, 2025 17:23
@llvmbot
Copy link
Member

llvmbot commented Jun 3, 2025

@llvm/pr-subscribers-libc

Author: Michael Jones (michaelrj-google)

Changes

The previous implementations called other entrypoints. This patch fixes
strcat and strncat to be properly independent.


Full diff: https://github.com/llvm/llvm-project/pull/142643.diff

3 Files Affected:

  • (modified) libc/src/string/CMakeLists.txt (-2)
  • (modified) libc/src/string/strcat.cpp (+5-4)
  • (modified) libc/src/string/strncat.cpp (+5-4)
diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt
index 2c607bf8ea895..0e9fc33418515 100644
--- a/libc/src/string/CMakeLists.txt
+++ b/libc/src/string/CMakeLists.txt
@@ -110,7 +110,6 @@ add_entrypoint_object(
   HDRS
     strcat.h
   DEPENDS
-    .strcpy
     .string_utils
     libc.include.llvm-libc-types.size_t
 )
@@ -267,7 +266,6 @@ add_entrypoint_object(
   HDRS
     strncat.h
   DEPENDS
-    .strncpy
     .string_utils
     libc.include.llvm-libc-types.size_t
 )
diff --git a/libc/src/string/strcat.cpp b/libc/src/string/strcat.cpp
index 0eb189ce204f0..4b6717c3c98e5 100644
--- a/libc/src/string/strcat.cpp
+++ b/libc/src/string/strcat.cpp
@@ -8,7 +8,6 @@
 
 #include "src/string/strcat.h"
 #include "src/__support/macros/config.h"
-#include "src/string/strcpy.h"
 #include "src/string/string_utils.h"
 
 #include "src/__support/common.h"
@@ -18,9 +17,11 @@ namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(char *, strcat,
                    (char *__restrict dest, const char *__restrict src)) {
   size_t dest_length = internal::string_length(dest);
-  size_t src_length = internal::string_length(src);
-  LIBC_NAMESPACE::strcpy(dest + dest_length, src);
-  dest[dest_length + src_length] = '\0';
+  size_t i;
+  for (i = 0; src[i] != '\0'; ++i)
+    dest[dest_length + i] = src[i];
+
+  dest[dest_length + i] = '\0';
   return dest;
 }
 
diff --git a/libc/src/string/strncat.cpp b/libc/src/string/strncat.cpp
index 221881f93c47a..abd8d001f779c 100644
--- a/libc/src/string/strncat.cpp
+++ b/libc/src/string/strncat.cpp
@@ -18,11 +18,12 @@ namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(char *, strncat,
                    (char *__restrict dest, const char *__restrict src,
                     size_t count)) {
-  size_t src_length = internal::string_length(src);
-  size_t copy_amount = src_length > count ? count : src_length;
   size_t dest_length = internal::string_length(dest);
-  LIBC_NAMESPACE::strncpy(dest + dest_length, src, copy_amount);
-  dest[dest_length + copy_amount] = '\0';
+  size_t i;
+  for (i = 0; i < count && src[i] != '\0'; ++i)
+    dest[dest_length + i] = src[i];
+
+  dest[dest_length + i] = '\0';
   return dest;
 }
 

@michaelrj-google michaelrj-google changed the title [libc] Independent strcat/strncat [libc] Independent strcat/strncat/stpcpy Jun 4, 2025
@michaelrj-google
Copy link
Contributor Author

fixed merge conflict and switched to __builtin_memcpy

@@ -18,7 +17,7 @@ namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(char *, stpcpy,
(char *__restrict dest, const char *__restrict src)) {
size_t size = internal::string_length(src) + 1;
inline_memcpy(dest, src, size);
__builtin_memcpy(dest, src, size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a definition for this in libc/src/string/memory_utils/generic/builtin.h.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason to call that version instead of calling the builtin directly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly was wondering if there would be an easier way to select which flavor of memcpy we wanted. Might've been better as a template function than this macro dispatch but that's a big change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be interested in making memcpy specialization template controlled, though to keep the includes for different architectures separate we would probably still need some amount of macro control. I think that's probably a topic for a separate PR though.

The previous implementations called other entrypoints. This patch fixes
strcat and strncat to be properly independent.
@michaelrj-google
Copy link
Contributor Author

rebased, planning to merge once presubmits finish

@michaelrj-google michaelrj-google merged commit 28c14d4 into llvm:main Jun 12, 2025
13 checks passed
@michaelrj-google michaelrj-google deleted the libcStrcatFix branch June 12, 2025 22:58
tomtor pushed a commit to tomtor/llvm-project that referenced this pull request Jun 14, 2025
The previous implementations called other entrypoints. This patch fixes
strcat, strncat, and stpcpy to be properly independent.
akuhlens pushed a commit to akuhlens/llvm-project that referenced this pull request Jun 24, 2025
The previous implementations called other entrypoints. This patch fixes
strcat, strncat, and stpcpy to be properly independent.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants