diff options
author | Sam Elliott <selliott@lowrisc.org> | 2019-10-09 11:01:46 +0000 |
---|---|---|
committer | Sam Elliott <selliott@lowrisc.org> | 2019-10-09 11:01:46 +0000 |
commit | 7680b39a7d6ca81a9b04f85c62c7d1fd9bc4c807 (patch) | |
tree | 9fdfeaed7778d64bc263a073e30286f121ffd799 /SingleSource/Regression/C/gcc-c-torture/execute/strlen-6.c | |
parent | 26f2bc886b4fe7d9caa4948e8ada2ce2fcc76faf (diff) |
Add GCC Torture Suite Sources
git-svn-id: https://llvm.org/svn/llvm-project/test-suite/trunk@374156 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'SingleSource/Regression/C/gcc-c-torture/execute/strlen-6.c')
-rw-r--r-- | SingleSource/Regression/C/gcc-c-torture/execute/strlen-6.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/SingleSource/Regression/C/gcc-c-torture/execute/strlen-6.c b/SingleSource/Regression/C/gcc-c-torture/execute/strlen-6.c new file mode 100644 index 00000000..1df5b21f --- /dev/null +++ b/SingleSource/Regression/C/gcc-c-torture/execute/strlen-6.c @@ -0,0 +1,113 @@ +/* Test to verify that strlen() calls with conditional expressions + and unterminated arrays or pointers to such things as arguments + are evaluated without making assumptions about array sizes. */ + +extern __SIZE_TYPE__ strlen (const char *); + +unsigned nfails; + +#define A(expr, N) \ + do { \ + const char *_s = (expr); \ + unsigned _n = strlen (_s); \ + ((_n == N) \ + ? 0 \ + : (__builtin_printf ("line %i: strlen ((%s) = (\"%s\"))" \ + " == %u failed\n", \ + __LINE__, #expr, _s, N), \ + ++nfails)); \ + } while (0) + + +volatile int i0 = 0; + +const char ca[2][3] = { "12" }; +const char cb[2][3] = { { '1', '2', '3', }, { '4' } }; + +char va[2][3] = { "123" }; +char vb[2][3] = { { '1', '2', '3', }, { '4', '5' } }; + +const char *s = "123456"; + + +static void test_binary_cond_expr_global (void) +{ + A (i0 ? "1" : ca[0], 2); + A (i0 ? ca[0] : "123", 3); + + /* The call to strlen (cb[0]) is strictly undefined because the array + isn't nul-terminated. This test verifies that the strlen range + optimization doesn't assume that the argument is necessarily nul + terminated. + Ditto for strlen (vb[0]). */ + A (i0 ? "1" : cb[0], 4); /* GCC 8.2 failure */ + A (i0 ? cb[0] : "12", 2); + + A (i0 ? "1" : va[0], 3); /* GCC 8.2 failure */ + A (i0 ? va[0] : "1234", 4); + + A (i0 ? "1" : vb[0], 5); /* GCC 8.2 failure */ + A (i0 ? vb[0] : "12", 2); +} + + +static void test_binary_cond_expr_local (void) +{ + const char lca[2][3] = { "12" }; + const char lcb[2][3] = { { '1', '2', '3', }, { '4' } }; + + char lva[2][3] = { "123" }; + char lvb[2][3] = { { '1', '2', '3', }, { '4', '5' } }; + + /* Also undefined as above. */ + A (i0 ? "1" : lca[0], 2); + A (i0 ? lca[0] : "123", 3); + + A (i0 ? "1" : lcb[0], 4); /* GCC 8.2 failure */ + A (i0 ? lcb[0] : "12", 2); + + A (i0 ? "1" : lva[0], 3); /* GCC 8.2 failure */ + A (i0 ? lva[0] : "1234", 4); + + A (i0 ? "1" : lvb[0], 5); /* GCC 8.2 failure */ + A (i0 ? lvb[0] : "12", 2); +} + + +static void test_ternary_cond_expr (void) +{ + /* Also undefined. */ + A (i0 == 0 ? s : i0 == 1 ? vb[0] : "123", 6); + A (i0 == 0 ? vb[0] : i0 == 1 ? s : "123", 5); + A (i0 == 0 ? "123" : i0 == 1 ? s : vb[0], 3); +} + + +const char (*pca)[3] = &ca[0]; +const char (*pcb)[3] = &cb[0]; + +char (*pva)[3] = &va[0]; +char (*pvb)[3] = &vb[0]; + +static void test_binary_cond_expr_arrayptr (void) +{ + /* Also undefined. */ + A (i0 ? *pca : *pcb, 4); /* GCC 8.2 failure */ + A (i0 ? *pcb : *pca, 2); + + A (i0 ? *pva : *pvb, 5); /* GCC 8.2 failure */ + A (i0 ? *pvb : *pva, 3); +} + + +int main (void) +{ + test_binary_cond_expr_global (); + test_binary_cond_expr_local (); + + test_ternary_cond_expr (); + test_binary_cond_expr_arrayptr (); + + if (nfails) + __builtin_abort (); +} |