libc: add clang FORTIFY support

This patch adds clang-style FORTIFY to Bionic. For more information on
FORTIFY, please see https://goo.gl/8HS2dW . This implementation works
for versions of clang that don't support diagnose_if, so please see the
"without diagnose_if" sections. We plan to swap to a diagnose_if-based
FORTIFY later this year (since it doesn't really add any features; it
just simplifies the implementation a lot, and it gives us much prettier
diagnostics)

Bug: 32073964
Test: Builds on angler, bullhead, marlin, sailfish. Bionic CTS tests
pass on Angler and Bullhead.

Change-Id: I607aecbeee81529709b1eee7bef5b0836151eb2b
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index d0c08e1..eefee13 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -83,8 +83,9 @@
 long atol(const char*) __attribute_pure__;
 long long atoll(const char*) __attribute_pure__;
 
-char* realpath(const char* path, char* resolved);
-int system(const char* string);
+char * realpath(const char *path, char *resolved) __overloadable
+        __RENAME_CLANG(realpath);
+int system(const char *string);
 
 void* bsearch(const void* key, const void* base0, size_t nmemb, size_t size,
               int (*compar)(const void*, const void*));
@@ -164,24 +165,44 @@
 #endif
 
 #if defined(__BIONIC_FORTIFY)
+#define __realpath_buf_too_small_str \
+    "realpath output parameter must be NULL or a >= PATH_MAX bytes buffer"
+
+/* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */
+#define __PATH_MAX 4096
+
+#if defined(__clang__)
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+char* realpath(const char* path, char* resolved) __overloadable
+    __enable_if(__bos(resolved) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                __bos(resolved) < __PATH_MAX, __realpath_buf_too_small_str)
+    __errorattr(__realpath_buf_too_small_str);
+
+/* No need for a FORTIFY version; the only things we can catch are at
+ * compile-time.
+ */
+
+#else /* defined(__clang__) */
 
 char* __realpath_real(const char*, char*) __RENAME(realpath);
-__errordecl(__realpath_size_error, "realpath output parameter must be NULL or a >= PATH_MAX bytes buffer");
+__errordecl(__realpath_size_error, __realpath_buf_too_small_str);
 
-#if !defined(__clang__)
 __BIONIC_FORTIFY_INLINE
 char* realpath(const char* path, char* resolved) {
     size_t bos = __bos(resolved);
 
-    /* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */
-    if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < 4096) {
+    if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < __PATH_MAX) {
         __realpath_size_error();
     }
 
     return __realpath_real(path, resolved);
 }
-#endif
 
+#endif /* defined(__clang__) */
+
+#undef __PATH_MAX
+#undef __realpath_buf_too_small_str
 #endif /* defined(__BIONIC_FORTIFY) */
 
 #if __ANDROID_API__ >= __ANDROID_API_L__