aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2018-07-25 02:11:31 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2018-07-24 20:11:31 -0600
commitbfb9bd47b2daac0a01c561effac1d8244ddd99f6 (patch)
treebf72d7afae065152f74b4f862adffad1c954d61e /gcc/testsuite
parentae752f020fd86b2d34a1556124dc4e5f01a8dcce (diff)
downloadgcc-bfb9bd47b2daac0a01c561effac1d8244ddd99f6.zip
gcc-bfb9bd47b2daac0a01c561effac1d8244ddd99f6.tar.gz
gcc-bfb9bd47b2daac0a01c561effac1d8244ddd99f6.tar.bz2
PR tree-optimization/86622 - incorrect strlen of array of array plus variable offset
PR tree-optimization/86622 - incorrect strlen of array of array plus variable offset PR tree-optimization/86532 - Wrong code due to a wrong strlen folding starting with r262522 gcc/ChangeLog: PR tree-optimization/86622 PR tree-optimization/86532 * builtins.h (string_length): Declare. * builtins.c (c_strlen): Correct handling of non-constant offsets. (check_access): Be prepared for non-constant length ranges. (string_length): Make extern. * expr.c (string_constant): Only handle the minor non-constant array index. Use string_constant to compute the length of a generic string constant. gcc/testsuite/ChangeLog: PR tree-optimization/86622 PR tree-optimization/86532 * gcc.c-torture/execute/strlen-2.c: New test. * gcc.c-torture/execute/strlen-3.c: New test. * gcc.c-torture/execute/strlen-4.c: New test. From-SVN: r262958
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/strlen-2.c210
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/strlen-3.c132
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/strlen-4.c232
4 files changed, 582 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f8cf9ee..af40567 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2018-07-24 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/86622
+ PR tree-optimization/86532
+ * gcc.c-torture/execute/strlen-2.c: New test.
+ * gcc.c-torture/execute/strlen-3.c: New test.
+ * gcc.c-torture/execute/strlen-4.c: New test.
+
2018-07-24 David Malcolm <dmalcolm@redhat.com>
PR tree-optimization/86636
diff --git a/gcc/testsuite/gcc.c-torture/execute/strlen-2.c b/gcc/testsuite/gcc.c-torture/execute/strlen-2.c
new file mode 100644
index 0000000..4519f6a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/strlen-2.c
@@ -0,0 +1,210 @@
+/* PR tree-optimization/86532 - Wrong code due to a wrong strlen folding */
+
+extern __SIZE_TYPE__ strlen (const char*);
+
+static const char a[2][3] = { "1", "12" };
+static const char b[2][2][5] = { { "1", "12" }, { "123", "1234" } };
+
+volatile int v0 = 0;
+volatile int v1 = 1;
+volatile int v2 = 2;
+
+#define A(expr) \
+ ((expr) ? (void)0 : (__builtin_printf ("assertion on line %i: %s\n", \
+ __LINE__, #expr), \
+ __builtin_abort ()))
+
+void test_array_ref_2_3 (void)
+{
+ A (strlen (a[v0]) == 1);
+ A (strlen (&a[v0][v0]) == 1);
+ A (strlen (&a[0][v0]) == 1);
+ A (strlen (&a[v0][0]) == 1);
+
+ A (strlen (a[v1]) == 2);
+ A (strlen (&a[v1][0]) == 2);
+ A (strlen (&a[1][v0]) == 2);
+ A (strlen (&a[v1][v0]) == 2);
+
+ A (strlen (&a[v1][1]) == 1);
+ A (strlen (&a[v1][1]) == 1);
+
+ A (strlen (&a[v1][2]) == 0);
+ A (strlen (&a[v1][v2]) == 0);
+
+ int i0 = 0;
+ int i1 = i0 + 1;
+ int i2 = i1 + 1;
+
+ A (strlen (a[v0]) == 1);
+ A (strlen (&a[v0][v0]) == 1);
+ A (strlen (&a[i0][v0]) == 1);
+ A (strlen (&a[v0][i0]) == 1);
+
+ A (strlen (a[v1]) == 2);
+ A (strlen (&a[v1][i0]) == 2);
+ A (strlen (&a[i1][v0]) == 2);
+ A (strlen (&a[v1][v0]) == 2);
+
+ A (strlen (&a[v1][i1]) == 1);
+ A (strlen (&a[v1][i1]) == 1);
+
+ A (strlen (&a[v1][i2]) == 0);
+ A (strlen (&a[v1][v2]) == 0);
+}
+
+void test_array_off_2_3 (void)
+{
+ A (strlen (a[0] + 0) == 1);
+ A (strlen (a[0] + v0) == 1);
+ A (strlen (a[v0] + 0) == 1);
+ A (strlen (a[v0] + v0) == 1);
+
+ A (strlen (a[v1] + 0) == 2);
+ A (strlen (a[1] + v0) == 2);
+ A (strlen (a[v1] + 0) == 2);
+ A (strlen (a[v1] + v0) == 2);
+
+ A (strlen (a[v1] + 1) == 1);
+ A (strlen (a[v1] + v1) == 1);
+
+ A (strlen (a[v1] + 2) == 0);
+ A (strlen (a[v1] + v2) == 0);
+
+ int i0 = 0;
+ int i1 = i0 + 1;
+ int i2 = i1 + 1;
+
+ A (strlen (a[i0] + i0) == 1);
+ A (strlen (a[i0] + v0) == 1);
+ A (strlen (a[v0] + i0) == 1);
+ A (strlen (a[v0] + v0) == 1);
+
+ A (strlen (a[v1] + i0) == 2);
+ A (strlen (a[i1] + v0) == 2);
+ A (strlen (a[v1] + i0) == 2);
+ A (strlen (a[v1] + v0) == 2);
+
+ A (strlen (a[v1] + i1) == 1);
+ A (strlen (a[v1] + v1) == 1);
+
+ A (strlen (a[v1] + i2) == 0);
+ A (strlen (a[v1] + v2) == 0);
+}
+
+void test_array_ref_2_2_5 (void)
+{
+ A (strlen (b[0][v0]) == 1);
+ A (strlen (b[v0][0]) == 1);
+
+ A (strlen (&b[0][0][v0]) == 1);
+ A (strlen (&b[0][v0][0]) == 1);
+ A (strlen (&b[v0][0][0]) == 1);
+
+ A (strlen (&b[0][v0][v0]) == 1);
+ A (strlen (&b[v0][0][v0]) == 1);
+ A (strlen (&b[v0][v0][0]) == 1);
+
+ A (strlen (b[0][v1]) == 2);
+ A (strlen (b[v1][0]) == 3);
+
+ A (strlen (&b[0][0][v1]) == 0);
+ A (strlen (&b[0][v1][0]) == 2);
+ A (strlen (&b[v0][0][0]) == 1);
+
+ A (strlen (&b[0][v0][v0]) == 1);
+ A (strlen (&b[v0][0][v0]) == 1);
+ A (strlen (&b[v0][v0][0]) == 1);
+
+ A (strlen (&b[0][v1][v1]) == 1);
+ A (strlen (&b[v1][0][v1]) == 2);
+ A (strlen (&b[v1][v1][0]) == 4);
+ A (strlen (&b[v1][v1][1]) == 3);
+ A (strlen (&b[v1][v1][2]) == 2);
+
+ int i0 = 0;
+ int i1 = i0 + 1;
+ int i2 = i1 + 1;
+
+ A (strlen (b[i0][v0]) == 1);
+ A (strlen (b[v0][i0]) == 1);
+
+ A (strlen (&b[i0][i0][v0]) == 1);
+ A (strlen (&b[i0][v0][i0]) == 1);
+ A (strlen (&b[v0][i0][i0]) == 1);
+
+ A (strlen (&b[i0][v0][v0]) == 1);
+ A (strlen (&b[v0][i0][v0]) == 1);
+ A (strlen (&b[v0][v0][i0]) == 1);
+
+ A (strlen (b[i0][v1]) == 2);
+ A (strlen (b[v1][i0]) == 3);
+
+ A (strlen (&b[i0][i0][v1]) == 0);
+ A (strlen (&b[i0][v1][i0]) == 2);
+ A (strlen (&b[v0][i0][i0]) == 1);
+
+ A (strlen (&b[i0][v0][v0]) == 1);
+ A (strlen (&b[v0][i0][v0]) == 1);
+ A (strlen (&b[v0][v0][i0]) == 1);
+
+ A (strlen (&b[i0][v1][v1]) == 1);
+ A (strlen (&b[v1][i0][v1]) == 2);
+ A (strlen (&b[v1][v1][i0]) == 4);
+ A (strlen (&b[v1][v1][i1]) == 3);
+ A (strlen (&b[v1][v1][i2]) == 2);
+}
+
+void test_array_off_2_2_5 (void)
+{
+ A (strlen (b[0][0] + v0) == 1);
+ A (strlen (b[0][v0] + v0) == 1);
+ A (strlen (b[v0][0] + v0) == 1);
+ A (strlen (b[v0][v0] + v0) == 1);
+
+ A (strlen (b[0][0] + v1) == 0);
+ A (strlen (b[0][v1] + 0) == 2);
+ A (strlen (b[v0][0] + 0) == 1);
+
+ A (strlen (b[0][v0] + v0) == 1);
+ A (strlen (b[v0][0] + v0) == 1);
+ A (strlen (b[v0][v0] + 0) == 1);
+
+ A (strlen (b[0][v1] + v1) == 1);
+ A (strlen (b[v1][0] + v1) == 2);
+ A (strlen (b[v1][v1] + 0) == 4);
+ A (strlen (b[v1][v1] + 1) == 3);
+ A (strlen (b[v1][v1] + 2) == 2);
+
+ int i0 = 0;
+ int i1 = i0 + 1;
+ int i2 = i1 + 1;
+
+ A (strlen (b[i0][i0] + v0) == 1);
+ A (strlen (b[i0][v0] + v0) == 1);
+ A (strlen (b[v0][i0] + v0) == 1);
+ A (strlen (b[v0][v0] + v0) == 1);
+
+ A (strlen (b[i0][i0] + v1) == 0);
+ A (strlen (b[i0][v1] + i0) == 2);
+ A (strlen (b[v0][i0] + i0) == 1);
+
+ A (strlen (b[i0][v0] + v0) == 1);
+ A (strlen (b[v0][i0] + v0) == 1);
+ A (strlen (b[v0][v0] + i0) == 1);
+
+ A (strlen (b[i0][v1] + v1) == 1);
+ A (strlen (b[v1][i0] + v1) == 2);
+ A (strlen (b[v1][v1] + i0) == 4);
+ A (strlen (b[v1][v1] + i1) == 3);
+ A (strlen (b[v1][v1] + i2) == 2);
+}
+
+int main ()
+{
+ test_array_ref_2_3 ();
+ test_array_off_2_3 ();
+
+ test_array_ref_2_2_5 ();
+ test_array_off_2_2_5 ();
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/strlen-3.c b/gcc/testsuite/gcc.c-torture/execute/strlen-3.c
new file mode 100644
index 0000000..182afdd
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/strlen-3.c
@@ -0,0 +1,132 @@
+/* PR tree-optimization/86532 - Wrong code due to a wrong strlen folding
+ starting with r262522
+ Exercise strlen() with a multi-dimensional array of strings with
+ embedded nuls. */
+
+extern __SIZE_TYPE__ strlen (const char*);
+
+static const char a[2][3][9] = {
+ { "1", "1\0002" },
+ { "12\0003", "123\0004" }
+};
+
+volatile int v0 = 0;
+volatile int v1 = 1;
+volatile int v2 = 2;
+volatile int v3 = 3;
+volatile int v4 = 4;
+volatile int v5 = 5;
+volatile int v6 = 6;
+volatile int v7 = 7;
+
+#define A(expr) \
+ ((expr) ? (void)0 : (__builtin_printf ("assertion on line %i: %s\n", \
+ __LINE__, #expr), \
+ __builtin_abort ()))
+
+void test_array_ref (void)
+{
+ int i0 = 0;
+ int i1 = i0 + 1;
+ int i2 = i1 + 1;
+ int i3 = i2 + 1;
+ int i4 = i3 + 1;
+ int i5 = i4 + 1;
+ int i6 = i5 + 1;
+ int i7 = i6 + 1;
+
+ A (strlen (a[0][0]) == 1);
+ A (strlen (a[0][1]) == 1);
+
+ A (strlen (a[1][0]) == 2);
+ A (strlen (a[1][1]) == 3);
+
+ A (strlen (&a[0][0][0]) == 1);
+ A (strlen (&a[0][1][0]) == 1);
+
+ A (strlen (&a[1][0][0]) == 2);
+ A (strlen (&a[1][1][0]) == 3);
+
+ A (strlen (&a[0][0][0] + 1) == 0);
+ A (strlen (&a[0][1][0] + 1) == 0);
+ A (strlen (&a[0][1][0] + 2) == 1);
+ A (strlen (&a[0][1][0] + 3) == 0);
+ A (strlen (&a[0][1][0] + 7) == 0);
+
+ A (strlen (&a[1][0][0] + 1) == 1);
+ A (strlen (&a[1][1][0] + 1) == 2);
+ A (strlen (&a[1][1][0] + 2) == 1);
+ A (strlen (&a[1][1][0] + 7) == 0);
+
+
+ A (strlen (a[i0][i0]) == 1);
+ A (strlen (a[i0][i1]) == 1);
+
+ A (strlen (a[i1][i0]) == 2);
+ A (strlen (a[i1][i1]) == 3);
+
+ A (strlen (&a[i0][i0][i0]) == 1);
+ A (strlen (&a[i0][i1][i0]) == 1);
+ A (strlen (&a[i0][i1][i1]) == 0);
+ A (strlen (&a[i0][i1][i2]) == 1);
+ A (strlen (&a[i0][i1][i3]) == 0);
+ A (strlen (&a[i0][i1][i3]) == 0);
+
+ A (strlen (&a[i1][i0][i0]) == 2);
+ A (strlen (&a[i1][i1][i0]) == 3);
+ A (strlen (&a[i1][i1][i1]) == 2);
+ A (strlen (&a[i1][i1][i2]) == 1);
+ A (strlen (&a[i1][i1][i3]) == 0);
+ A (strlen (&a[i1][i1][i4]) == 1);
+ A (strlen (&a[i1][i1][i5]) == 0);
+ A (strlen (&a[i1][i1][i6]) == 0);
+ A (strlen (&a[i1][i1][i7]) == 0);
+
+ A (strlen (&a[i0][i0][i0] + i1) == 0);
+ A (strlen (&a[i0][i1][i0] + i1) == 0);
+ A (strlen (&a[i0][i1][i0] + i7) == 0);
+
+ A (strlen (&a[i1][i0][i0] + i1) == 1);
+ A (strlen (&a[i1][i1][i0] + i1) == 2);
+ A (strlen (&a[i1][i1][i0] + i2) == 1);
+ A (strlen (&a[i1][i1][i0] + i3) == 0);
+ A (strlen (&a[i1][i1][i0] + i4) == 1);
+ A (strlen (&a[i1][i1][i0] + i5) == 0);
+ A (strlen (&a[i1][i1][i0] + i6) == 0);
+ A (strlen (&a[i1][i1][i0] + i7) == 0);
+
+
+ A (strlen (a[i0][i0]) == 1);
+ A (strlen (a[i0][i1]) == 1);
+
+ A (strlen (a[i1][i0]) == 2);
+ A (strlen (a[i1][i1]) == 3);
+
+ A (strlen (&a[i0][i0][i0]) == 1);
+ A (strlen (&a[i0][i1][i0]) == 1);
+
+ A (strlen (&a[i1][i0][i0]) == 2);
+ A (strlen (&a[i1][i1][i0]) == 3);
+
+ A (strlen (&a[i0][i0][i0] + v1) == 0);
+ A (strlen (&a[i0][i0][i0] + v2) == 0);
+ A (strlen (&a[i0][i0][i0] + v7) == 0);
+
+ A (strlen (&a[i0][i1][i0] + v1) == 0);
+ A (strlen (&a[i0][i1][i0] + v2) == 1);
+ A (strlen (&a[i0][i1][i0] + v3) == 0);
+
+ A (strlen (&a[i1][i0][i0] + v1) == 1);
+ A (strlen (&a[i1][i1][i0] + v1) == 2);
+ A (strlen (&a[i1][i1][i0] + v2) == 1);
+ A (strlen (&a[i1][i1][i0] + v3) == 0);
+ A (strlen (&a[i1][i1][i0] + v4) == 1);
+ A (strlen (&a[i1][i1][i0] + v5) == 0);
+ A (strlen (&a[i1][i1][i0] + v6) == 0);
+ A (strlen (&a[i1][i1][i0] + v7) == 0);
+}
+
+int main (void)
+{
+ test_array_ref ();
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/strlen-4.c b/gcc/testsuite/gcc.c-torture/execute/strlen-4.c
new file mode 100644
index 0000000..c3b2c77
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/strlen-4.c
@@ -0,0 +1,232 @@
+/* PR tree-optimization/86622 - incorrect strlen of array of array plus
+ variable offset
+ Exercise strlen() with a multi-dimensional array of strings with
+ offsets. */
+
+extern int printf (const char*, ...);
+extern __SIZE_TYPE__ strlen (const char*);
+
+typedef char A28[28];
+typedef A28 A3_28[3];
+typedef A3_28 A2_3_28[2];
+
+static const A2_3_28 a = {
+ /* [0][0] [0][1] [0][2] */
+ { "1\00012", "123\0001234", "12345\000123456" },
+ /* [1][0] [1][1] [1][2] */
+ { "1234567\00012345678", "123456789\0001234567890", "12345678901\000123456789012" }
+};
+
+volatile int v0 = 0;
+volatile int v1 = 1;
+volatile int v2 = 2;
+volatile int v3 = 3;
+volatile int v4 = 4;
+volatile int v5 = 5;
+volatile int v6 = 6;
+volatile int v7 = 7;
+
+#define A(expr, N) \
+ ((strlen (expr) == N) \
+ ? (void)0 : (printf ("line %i: strlen (%s = \"%s\") != %i\n", \
+ __LINE__, #expr, expr, N), \
+ __builtin_abort ()))
+
+/* Verify that strlen() involving pointer to array arguments computes
+ the correct result. */
+
+void test_array_ptr (void)
+{
+ /* Compute the length of the string at the refeenced array. */
+ A (*(&a[0][0] + 0), 1);
+ A (*(&a[0][0] + 1), 3);
+ A (*(&a[0][0] + 2), 5);
+
+ A (*(&a[0][1] - 1), 1);
+ A (*(&a[0][1] + 0), 3);
+ A (*(&a[0][1] + 1), 5);
+
+ A (*(&a[0][2] - 2), 1);
+ A (*(&a[0][2] - 1), 3);
+ A (*(&a[0][2] + 0), 5);
+
+ A (*(&a[1][0] + 0), 7);
+ A (*(&a[1][0] + 1), 9);
+ A (*(&a[1][0] + 2), 11);
+
+ A (*(&a[1][1] - 1), 7);
+ A (*(&a[1][1] + 0), 9);
+ A (*(&a[1][1] + 1), 11);
+
+ A (*(&a[1][2] - 2), 7);
+ A (*(&a[1][2] - 1), 9);
+ A (*(&a[1][2] - 0), 11);
+
+ /* Compute the length of the string past the first nul. */
+ A (*(&a[0][0] + 0) + 2, 2);
+ A (*(&a[0][0] + 1) + 4, 4);
+ A (*(&a[0][0] + 2) + 6, 6);
+
+ /* Compute the length of the string past the second nul. */
+ A (*(&a[0][0] + 0) + 5, 0);
+ A (*(&a[0][0] + 1) + 10, 0);
+ A (*(&a[0][0] + 2) + 14, 0);
+
+ int i0 = 0;
+ int i1 = i0 + 1;
+ int i2 = i1 + 1;
+ int i3 = i2 + 1;
+ int i4 = i3 + 1;
+ int i5 = i4 + 1;
+
+ A (*(&a[0][0] + i0), 1);
+ A (*(&a[0][0] + i1), 3);
+ A (*(&a[0][0] + i2), 5);
+
+ A (*(&a[0][1] - i1), 1);
+ A (*(&a[0][1] + i0), 3);
+ A (*(&a[0][1] + i1), 5);
+
+ A (*(&a[0][2] - i2), 1);
+ A (*(&a[0][2] - i1), 3);
+ A (*(&a[0][2] + i0), 5);
+
+ A (*(&a[1][0] + i0), 7);
+ A (*(&a[1][0] + i1), 9);
+ A (*(&a[1][0] + i2), 11);
+
+ A (*(&a[1][1] - i1), 7);
+ A (*(&a[1][1] + i0), 9);
+ A (*(&a[1][1] + i1), 11);
+
+ A (*(&a[1][2] - i2), 7);
+ A (*(&a[1][2] - i1), 9);
+ A (*(&a[1][2] - i0), 11);
+
+
+ A (*(&a[i0][i0] + i0), 1);
+ A (*(&a[i0][i0] + i1), 3);
+ A (*(&a[i0][i0] + i2), 5);
+
+ A (*(&a[i0][i1] - i1), 1);
+ A (*(&a[i0][i1] + i0), 3);
+ A (*(&a[i0][i1] + i1), 5);
+
+ A (*(&a[i0][i2] - i2), 1);
+ A (*(&a[i0][i2] - i1), 3);
+ A (*(&a[i0][i2] + i0), 5);
+
+ A (*(&a[i1][i0] + i0), 7);
+ A (*(&a[i1][i0] + i1), 9);
+ A (*(&a[i1][i0] + i2), 11);
+
+ A (*(&a[i1][i1] - i1), 7);
+ A (*(&a[i1][i1] + i0), 9);
+ A (*(&a[i1][i1] + i1), 11);
+
+ A (*(&a[i1][i2] - i2), 7);
+ A (*(&a[i1][i2] - i1), 9);
+ A (*(&a[i1][i2] - i0), 11);
+
+
+ A (*(&a[i0][i0] + v0), 1);
+ A (*(&a[i0][i0] + v1), 3);
+ A (*(&a[i0][i0] + v2), 5);
+
+ A (*(&a[i0][i1] - v1), 1);
+ A (*(&a[i0][i1] + v0), 3);
+ A (*(&a[i0][i1] + v1), 5);
+
+ A (*(&a[i0][i2] - v2), 1);
+ A (*(&a[i0][i2] - v1), 3);
+ A (*(&a[i0][i2] + v0), 5);
+
+ A (*(&a[i1][i0] + v0), 7);
+ A (*(&a[i1][i0] + v1), 9);
+ A (*(&a[i1][i0] + v2), 11);
+
+ A (*(&a[i1][i1] - v1), 7);
+ A (*(&a[i1][i1] + v0), 9);
+ A (*(&a[i1][i1] + v1), 11);
+
+ A (*(&a[i1][i2] - v2), 7);
+ A (*(&a[i1][i2] - v1), 9);
+ A (*(&a[i1][i2] - v0), 11);
+
+
+ A (*(&a[i0][i0] + v0) + i1, 0);
+ A (*(&a[i0][i0] + v1) + i2, 1);
+ A (*(&a[i0][i0] + v2) + i3, 2);
+
+ A (*(&a[i0][i1] - v1) + v1, 0);
+ A (*(&a[i0][i1] + v0) + v3, 0);
+ A (*(&a[i0][i1] + v1) + v5, 0);
+
+ A (*(&a[i0][v1] - i1) + i1, 0);
+ A (*(&a[i0][v1] + i0) + i3, 0);
+ A (*(&a[i0][v1] + i1) + i5, 0);
+}
+
+static const A3_28* const pa0 = &a[0];
+static const A3_28* const pa1 = &a[1];
+
+static const A3_28* const paa[] = { &a[0], &a[1] };
+
+/* Verify that strlen() involving pointers and arrays of pointers
+ to array arguments computes the correct result. */
+
+void test_ptr_array (void)
+{
+ int i0 = 0;
+ int i1 = i0 + 1;
+ int i2 = i1 + 1;
+ int i3 = i2 + 1;
+
+ A (*((*pa0) + i0), 1);
+ A (*((*pa0) + i1), 3);
+ A (*((*pa0) + i2), 5);
+
+ A (*(pa0[0] + i0), 1);
+ A (*(pa0[0] + i1), 3);
+ A (*(pa0[0] + i2), 5);
+
+ A ((*pa0)[i0] + i1, 0);
+ A ((*pa0)[i1] + i2, 1);
+ A ((*pa0)[i2] + i3, 2);
+
+
+ A (*((*pa1) + i0), 7);
+ A (*((*pa1) + i1), 9);
+ A (*((*pa1) + i2), 11);
+
+ A (*(pa1[0] + i0), 7);
+ A (*(pa1[0] + i1), 9);
+ A (*(pa1[0] + i2), 11);
+
+ A ((*pa1)[i0] + i1, 6);
+ A ((*pa1)[i1] + i2, 7);
+ A ((*pa1)[i2] + i3, 8);
+
+ A (*(*(paa[0]) + i0), 1);
+ A (*(*(paa[0]) + i1), 3);
+ A (*(*(paa[0]) + i2), 5);
+
+ A (*(*(paa[1]) + i0), 7);
+ A (*(*(paa[1]) + i1), 9);
+ A (*(*(paa[1]) + i2), 11);
+
+ A (*(*(paa[1]) - i1), 5);
+ A (*(*(paa[1]) - i2), 3);
+ A (*(*(paa[1]) - i3), 1);
+
+ A (*(*(paa[0]) + i0) + i1, 0);
+ A (*(*(paa[0]) + i1) + i2, 1);
+ A (*(*(paa[0]) + i2) + i3, 2);
+}
+
+int main (void)
+{
+ test_array_ptr ();
+
+ test_ptr_array ();
+}