[msan] Intercept stpcpy.


git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@185340 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc
index 7f298dc..04764b5 100644
--- a/lib/msan/msan_interceptors.cc
+++ b/lib/msan/msan_interceptors.cc
@@ -167,6 +167,14 @@
   return res;
 }
 
+INTERCEPTOR(char *, stpcpy, char *dest, const char *src) {  // NOLINT
+  ENSURE_MSAN_INITED();
+  SIZE_T n = REAL(strlen)(src);
+  char *res = REAL(stpcpy)(dest, src);  // NOLINT
+  __msan_copy_poison(dest, src, n + 1);
+  return res;
+}
+
 INTERCEPTOR(char *, strdup, char *src) {
   ENSURE_MSAN_INITED();
   SIZE_T n = REAL(strlen)(src);
@@ -1135,6 +1143,7 @@
   INTERCEPT_FUNCTION(wmemcpy);
   INTERCEPT_FUNCTION(wmemmove);
   INTERCEPT_FUNCTION(strcpy);  // NOLINT
+  INTERCEPT_FUNCTION(stpcpy);  // NOLINT
   INTERCEPT_FUNCTION(strdup);
   INTERCEPT_FUNCTION(__strdup);
   INTERCEPT_FUNCTION(strndup);
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc
index 44e3e9e..0af2f57 100644
--- a/lib/msan/tests/msan_test.cc
+++ b/lib/msan/tests/msan_test.cc
@@ -1033,6 +1033,19 @@
   EXPECT_POISONED(y[2]);
 }
 
+TEST(MemorySanitizer, stpcpy) {  // NOLINT
+  char* x = new char[3];
+  char* y = new char[3];
+  x[0] = 'a';
+  x[1] = *GetPoisoned<char>(1, 1);
+  x[2] = 0;
+  char *res = stpcpy(y, x);  // NOLINT
+  ASSERT_EQ(res, y + 2);
+  EXPECT_NOT_POISONED(y[0]);
+  EXPECT_POISONED(y[1]);
+  EXPECT_NOT_POISONED(y[2]);
+}
+
 TEST(MemorySanitizer, strtol) {
   char *e;
   assert(1 == strtol("1", &e, 10));