fortify: rewrite strlen to fold to a constant

This new spelling allows Clang, when parsing C, to fold `strlen("foo")`
into a constant in many more places.

This shouldn't be much of a performance diff, since LLVM is already
fully capable of folding `@__strlen_chk` into `@strlen` or a constant as
appropriate. Mostly it matters for places where constants may be
required, or may result in materially different codegen (e.g., static
initializers, array bounds, ...)

Bug: 139143453
Test: mma
Change-Id: Ib1636402a11338f6e05a731cc5a59c919cca09e8
diff --git a/tests/clang_fortify_tests.cpp b/tests/clang_fortify_tests.cpp
index f08fd1f..105c261 100644
--- a/tests/clang_fortify_tests.cpp
+++ b/tests/clang_fortify_tests.cpp
@@ -89,6 +89,8 @@
 #include <unistd.h>
 #include <wchar.h>
 
+#include <array>
+
 #ifndef COMPILATION_TESTS
 #include <android-base/silent_death_test.h>
 #include <gtest/gtest.h>
@@ -133,6 +135,25 @@
 
 const static int kBogusFD = -1;
 
+FORTIFY_TEST(strlen) {
+  auto run_strlen_with_contents = [&](std::array<char, 3> contents) {
+    // A lot of cruft is necessary to make this test DTRT. LLVM and Clang love to fold/optimize
+    // strlen calls, and that's the opposite of what we want to happen.
+
+    // Loop to convince LLVM that `contents` can never be known (since `xor volatile_value` can flip
+    // any bit in each elem of `contents`).
+    volatile char always_zero = 0;
+    for (char& c : contents) {
+      c ^= always_zero;
+    }
+    // Store in a volatile, so the strlen itself cannot be optimized out.
+    volatile size_t _strlen_result = strlen(&contents.front());
+  };
+
+  EXPECT_NO_DEATH(run_strlen_with_contents({'f', 'o', '\0'}));
+  EXPECT_FORTIFY_DEATH(run_strlen_with_contents({'f', 'o', 'o'}));
+}
+
 FORTIFY_TEST(string) {
   char small_buffer[8] = {};