Annotate fortify functions with diagnose_as_builtin

Bug: http://b/197147102
Bug: http://b/214080353

With https://reviews.llvm.org/D77491, clang got stricter when issuing
diagnostics regarding builtin functions.
https://reviews.llvm.org/D112024 adds a diagnose_as_builtin attribute
which lets it diagnose builtins even though their signature is slightly
different.  This patch adds diagnose_as_builtin attribute as needed.

Versioner is built with an older clang so it doesn't recognize this
attribute.  So this is added with a preprocessor check on clang
versions.  We can remove the version check once versioner gets updated
shortly after the compiler update.

Test: mmma bionic/tests with clang-r445002
Change-Id: I3d0d63ecdbea0cffe97eb5110e2d9f2a7595a38e
diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h
index 42698dd..77bdbb4 100644
--- a/libc/include/bits/fortify/stdio.h
+++ b/libc/include/bits/fortify/stdio.h
@@ -40,6 +40,7 @@
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE __printflike(3, 0)
 int vsnprintf(char* const __pass_object_size dest, size_t size, const char* format, va_list ap)
+        __diagnose_as_builtin(__builtin_vsnprintf, 1, 2, 3, 4)
         __overloadable {
     return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
 }
@@ -70,6 +71,7 @@
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_VARIADIC __printflike(3, 4)
 int snprintf(char* const __pass_object_size dest, size_t size, const char* format, ...)
+        __diagnose_as_builtin(__builtin_snprintf, 1, 2, 3)
         __overloadable {
     va_list va;
     va_start(va, format);
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
index beb5ff5..08bce2d 100644
--- a/libc/include/bits/fortify/string.h
+++ b/libc/include/bits/fortify/string.h
@@ -44,13 +44,16 @@
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE
 void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
+        __diagnose_as_builtin(__builtin_memcpy, 1, 2, 3)
         __overloadable {
     return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
 }
 
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE
-void* memmove(void* const dst __pass_object_size0, const void* src, size_t len) __overloadable {
+void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
+        __diagnose_as_builtin(__builtin_memmove, 1, 2, 3)
+        __overloadable {
     return __builtin___memmove_chk(dst, src, len, __bos0(dst));
 }
 #endif
@@ -59,6 +62,7 @@
 #if __ANDROID_API__ >= 30
 __BIONIC_FORTIFY_INLINE
 void* mempcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
+        __diagnose_as_builtin(__builtin_mempcpy, 1, 2, 3)
         __overloadable
         __clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount),
                          "'mempcpy' called with size bigger than buffer") {
@@ -87,6 +91,7 @@
 
 __BIONIC_FORTIFY_INLINE
 char* strcpy(char* const dst __pass_object_size, const char* src)
+        __diagnose_as_builtin(__builtin_strcpy, 1, 2)
         __overloadable
         __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
                          "'strcpy' called with string bigger than buffer") {
@@ -112,7 +117,9 @@
 #if __ANDROID_API__ >= 17 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE
-char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __overloadable {
+char* strncat(char* const dst __pass_object_size, const char* src, size_t n)
+       __diagnose_as_builtin(__builtin_strncat, 1, 2, 3)
+       __overloadable {
     return __builtin___strncat_chk(dst, src, n, __bos(dst));
 }
 #endif
@@ -120,6 +127,7 @@
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE
 void* memset(void* const s __pass_object_size0, int c, size_t n) __overloadable
+        __diagnose_as_builtin(__builtin_memset, 1, 2, 3)
         /* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
         __clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
 #if __ANDROID_API__ >= 17 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
@@ -157,6 +165,7 @@
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE
 char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
+        __diagnose_as_builtin(__builtin_stpncpy, 1, 2, 3)
         __overloadable {
     size_t bos_dst = __bos(dst);
     size_t bos_src = __bos(src);
@@ -172,6 +181,7 @@
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE
 char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
+        __diagnose_as_builtin(__builtin_strncpy, 1, 2, 3)
         __overloadable {
     size_t bos_dst = __bos(dst);
     size_t bos_src = __bos(src);
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 2556d11..99a200a 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -327,6 +327,13 @@
 
 #define __overloadable __attribute__((overloadable))
 
+// TODO(pirama) Remove this version check after switching to clang-r445002
+#if __clang_major__ == 14 && __clang_patchlevel__ >= 2
+#define __diagnose_as_builtin(...) __attribute__((diagnose_as_builtin(__VA_ARGS__)))
+#else
+#define __diagnose_as_builtin(...)
+#endif
+
 /* Used to tag non-static symbols that are private and never exposed by the shared library. */
 #define __LIBC_HIDDEN__ __attribute__((visibility("hidden")))