fortify: Migrate trivial cases to dynamic check macros

|__builtin_constant_p| has become more flexible in clang. In particular,
it's no longer forcibly lowered before inlining, so we can actually use
it on function parameters (or |__bos(param)|).

This CL tweaks things so that trivially safe calls to FORTIFY'ed
functions compile into direct calls to those functions, rather than to
their _chk counterparts. This will be the most impactful with things
like |memset|, |memcpy|, etc., since clang has way more flexibility
about how to lower those than it does with |__memset_chk|,
|__memcpy_chk|, ...

As noted in the comments, the spelling of the new macros is meant to
match closely with the spelling of our |__bos_static| macros used in
|diagnose_if|.

This isn't a full cleanup of all of the cases in which we can do this.
Just a start on the super simple cases.

Bug: 131861088
Test: m checkbuild; blueline boots.

Change-Id: I696f42ce4a65231e0c4a78a4c5133a6be1cb7708
diff --git a/libc/include/bits/fortify/socket.h b/libc/include/bits/fortify/socket.h
index c9387c0..35fad3d 100644
--- a/libc/include/bits/fortify/socket.h
+++ b/libc/include/bits/fortify/socket.h
@@ -45,7 +45,7 @@
                      "'recvfrom' called with size bigger than buffer") {
   size_t bos = __bos0(buf);
 
-  if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+  if (__bos_trivially_not_lt(bos, len)) {
     return __call_bypassing_fortify(recvfrom)(fd, buf, len, flags, src_addr, addr_len);
   }
   return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
@@ -60,7 +60,7 @@
                      "'sendto' called with size bigger than buffer") {
   size_t bos = __bos0(buf);
 
-  if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+  if (__bos_trivially_not_lt(bos, len)) {
     return __call_bypassing_fortify(sendto)(fd, buf, len, flags, dest_addr, addr_len);
   }
   return __sendto_chk(fd, buf, len, bos, flags, dest_addr, addr_len);
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
index 80eb43e..426076e 100644
--- a/libc/include/bits/fortify/string.h
+++ b/libc/include/bits/fortify/string.h
@@ -46,7 +46,11 @@
         __overloadable
         __clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount),
                          "'memcpy' called with size bigger than buffer") {
-    return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
+    size_t bos_dst = __bos0(dst);
+    if (__bos_trivially_not_lt(bos_dst, copy_amount)) {
+        return __builtin_memcpy(dst, src, copy_amount);
+    }
+    return __builtin___memcpy_chk(dst, src, copy_amount, bos_dst);
 }
 
 __BIONIC_FORTIFY_INLINE
@@ -54,7 +58,11 @@
         __overloadable
         __clang_error_if(__bos_unevaluated_lt(__bos0(dst), len),
                          "'memmove' called with size bigger than buffer") {
-    return __builtin___memmove_chk(dst, src, len, __bos0(dst));
+    size_t bos_dst = __bos0(dst);
+    if (__bos_trivially_not_lt(bos_dst, len)) {
+        return __builtin_memmove(dst, src, len);
+    }
+    return __builtin___memmove_chk(dst, src, len, bos_dst);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 
@@ -64,7 +72,11 @@
         __overloadable
         __clang_error_if(__bos_unevaluated_leq(__bos(dst), __builtin_strlen(src)),
                          "'stpcpy' called with string bigger than buffer") {
-    return __builtin___stpcpy_chk(dst, src, __bos(dst));
+    size_t bos_dst = __bos(dst);
+    if (__bos_trivially_not_leq(bos_dst, __builtin_strlen(src))) {
+        return __builtin_stpcpy(dst, src);
+    }
+    return __builtin___stpcpy_chk(dst, src, bos_dst);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
 
@@ -74,7 +86,11 @@
         __overloadable
         __clang_error_if(__bos_unevaluated_leq(__bos(dst), __builtin_strlen(src)),
                          "'strcpy' called with string bigger than buffer") {
-    return __builtin___strcpy_chk(dst, src, __bos(dst));
+    size_t bos_dst = __bos(dst);
+    if (__bos_trivially_not_leq(bos_dst, __builtin_strlen(src))) {
+        return __builtin_strcpy(dst, src);
+    }
+    return __builtin___strcpy_chk(dst, src, bos_dst);
 }
 
 __BIONIC_FORTIFY_INLINE
@@ -94,7 +110,11 @@
                          "'memset' called with size bigger than buffer")
         /* 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?") {
-    return __builtin___memset_chk(s, c, n, __bos0(s));
+    size_t bos = __bos0(s);
+    if (__bos_trivially_not_lt(bos, n)) {
+        return __builtin_memset(s, c, n);
+    }
+    return __builtin___memset_chk(s, c, n, bos);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index f36b78e..b4ae393 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -296,6 +296,13 @@
 #define __bos_unevaluated_leq(bos_val, val) \
   ((bos_val) != __BIONIC_FORTIFY_UNKNOWN_SIZE && (bos_val) <= (val))
 
+/* Intended for use in evaluated contexts. */
+#define __bos_dynamic_check_impl(bos_val, op, index) \
+  (bos_val == __BIONIC_FORTIFY_UNKNOWN_SIZE || (__builtin_constant_p(index) && bos_val op index))
+
+/* The names here are meant to match nicely with the __bos_unevaluated macros above. */
+#define __bos_trivially_not_lt(bos_val, index) __bos_dynamic_check_impl((bos_val), >=, (index))
+#define __bos_trivially_not_leq(bos_val, index) __bos_dynamic_check_impl((bos_val), >, (index))
 
 #if defined(__BIONIC_FORTIFY) || defined(__BIONIC_DECLARE_FORTIFY_HELPERS)
 #  define __BIONIC_INCLUDE_FORTIFY_HEADERS 1