diff options
author | Martin Sebor <msebor@redhat.com> | 2019-01-02 06:02:37 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2019-01-01 23:02:37 -0700 |
commit | 5d6655ebcc96030644f99eb1c431dd96e374db90 (patch) | |
tree | 254a28a425e845f22414200219cf3f13aec1f0a6 /gcc/testsuite/gcc.dg | |
parent | 79b1c2295b3031764904ce66ae294aa57aef50ae (diff) | |
download | gcc-5d6655ebcc96030644f99eb1c431dd96e374db90.zip gcc-5d6655ebcc96030644f99eb1c431dd96e374db90.tar.gz gcc-5d6655ebcc96030644f99eb1c431dd96e374db90.tar.bz2 |
gimple-fold.h (get_range_strlen): Update prototype.
* gimple-fold.h (get_range_strlen): Update prototype.
* builtins.c (check_access): Update call to get_range_strlen to use
c_strlen_data pointer. Change various variable accesses to instead
pull data from the c_strlen_data structure.
(check_strncat_sizes, expand_builtin_strncat): Likewise.
* calls.c (maybe_warn_nonstring_arg): Likewise.
* tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Likewise. Reset
minimum length if maximum lengh is unknown.
* gimple-ssa-sprintf.c (get_string_length): Likewise. Drop code
that used c_strlen, it's no longer needed. Restructure slightly.
(format_string): Set unlikely range appropriately.
* gimple-fold.c (get_range_strlen): Update comments. Fix minor
formatting issues.
(get_range_strlen): Accept c_strlen_data pointer for external
call sites as well. Pass through to call to internal get_range_strlen.
Adjust minlen, maxlen and maxbound as needed.
(get_maxval_strlen): Update comments.
(gimple_fold_builtin_strlen): Update call to get_range_strlen
to use c_strlen_data pointer. Change variable accesses to instead
use c_strlen_data data members.
* gcc.dg/strlenopt-40.c: Disable a couple tests.
* gcc.dg/strlenopt-48.c: Twiddle test.
* gcc.dg/strlenopt-59.c: New test.
* gcc.dg/tree-ssa/builtin-snprintf-5.c: New test.
* g++.dg/init/strlen.C: New test.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r267503
Diffstat (limited to 'gcc/testsuite/gcc.dg')
-rw-r--r-- | gcc/testsuite/gcc.dg/strlenopt-40.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/strlenopt-48.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/strlenopt-59.c | 73 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-5.c | 51 |
4 files changed, 129 insertions, 5 deletions
diff --git a/gcc/testsuite/gcc.dg/strlenopt-40.c b/gcc/testsuite/gcc.dg/strlenopt-40.c index f4577d6..e24b510 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-40.c +++ b/gcc/testsuite/gcc.dg/strlenopt-40.c @@ -124,8 +124,8 @@ void elim_global_arrays (int i) ELIM_TRUE (strlen (a7) < sizeof a7); ELIM_TRUE (strlen (ax) != DIFF_MAX); - ELIM_TRUE (strlen (ax) != DIFF_MAX - 1); - ELIM_TRUE (strlen (ax) < DIFF_MAX - 1); + /* ELIM_TRUE (strlen (ax) != DIFF_MAX - 1); */ + /* ELIM_TRUE (strlen (ax) < DIFF_MAX - 1); */ } void elim_pointer_to_arrays (void) diff --git a/gcc/testsuite/gcc.dg/strlenopt-48.c b/gcc/testsuite/gcc.dg/strlenopt-48.c index 39bb32d..179edd8 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-48.c +++ b/gcc/testsuite/gcc.dg/strlenopt-48.c @@ -11,7 +11,7 @@ void f (void) { extern char a[2][1]; int n = strlen (a[1]); - if (n) + if (n >= sizeof a) abort(); } @@ -19,7 +19,7 @@ void g (void) { extern char b[3][2][1]; int n = strlen (b[2][1]); - if (n) + if (n >= sizeof b) abort(); } @@ -27,7 +27,7 @@ void h (void) { extern char c[4][3][2][1]; int n = strlen (c[3][2][1]); - if (n) + if (n >= sizeof c) abort(); } diff --git a/gcc/testsuite/gcc.dg/strlenopt-59.c b/gcc/testsuite/gcc.dg/strlenopt-59.c new file mode 100644 index 0000000..9bacf87 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strlenopt-59.c @@ -0,0 +1,73 @@ +/* Verify that strlen() calls with constant conditional expressions are + eliminated as expected. + + { dg-do compile } + { dg-options "-O1 -fdump-tree-optimized" } */ + +extern void abort (void); +extern __SIZE_TYPE__ strlen (const char*); + + +#define CAT(x, y) x ## y +#define CONCAT(x, y) CAT (x, y) +#define FAILNAME(name) CONCAT (call_ ## name ##_on_line_, __LINE__) + +#define FAIL(name) do { \ + extern void FAILNAME (name) (void); \ + FAILNAME (name)(); \ + } while (0) + +/* Macros to emit a call to funcation named + call_failed_to_be_eliminated_on_line_NNN() + for each call that's expected to be eliminated. The dg-final + scan-tree-dump-time directive at the bottom of the test verifies + that no such call appears in output. */ +#define ELIM(expr) \ + if ((expr)) FAIL (test_not_eliminated); else (void)0 + +extern char a3[3]; +extern char a7[7]; + +struct MemArrays { char a[7], b[9]; }; + +struct MemArrays ma; + +void test_elim_condexpr (int i) +{ + ELIM (6 < strlen (i ? "" : "123456")); + ELIM (6 < strlen (i ? "123456" : "")); + + ELIM (4 < strlen (i < 1 ? "a" : i == 1 ? "ab" : "abc")); + + ELIM (3 < strlen (i ? "" : a3)); + ELIM (3 < strlen (i ? a3 : "1")); + + ELIM (6 < strlen (i ? "12" : a7)); + ELIM (6 < strlen (i ? a7 : "123")); + + ELIM (6 < strlen (i ? "1234" : a7)); + ELIM (7 < strlen (i ? a7 : "1234567")); + + ELIM (3 < strlen (i < 1 ? "a" : i == 1 ? "ab" : a3)); + ELIM (3 < strlen (i < 1 ? "a" : i == 1 ? a3 : "abc")); + ELIM (3 < strlen (i < 1 ? a3 : i == 1 ? "a" : "abc")); + + ELIM (6 < strlen (i < 1 ? "a" : i == 1 ? "ab" : a7)); + ELIM (6 < strlen (i < 1 ? "a" : i == 1 ? a7 : "abc")); + ELIM (6 < strlen (i < 1 ? a7 : i == 1 ? "a" : "abc")); + + ELIM (6 < strlen (i < 1 ? "a" : i == 1 ? a7 : a3)); + ELIM (6 < strlen (i < 1 ? a7 : i == 1 ? "a" : a3)); + + { + enum { maxlen = sizeof ma - 1 }; + ELIM (maxlen < strlen (ma.a)); + } + + { + enum { maxlen = sizeof ma - __builtin_offsetof (struct MemArrays, b) - 1 }; + ELIM (maxlen < strlen (ma.b)); + } +} + +/* { dg-final { scan-tree-dump-times "test_not_eliminated_" 0 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-5.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-5.c new file mode 100644 index 0000000..ad9a99b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-5.c @@ -0,0 +1,51 @@ +/* + { dg-do compile } + { dg-options "-O2 -Wall -fdump-tree-optimized" } */ + +typedef __SIZE_TYPE__ size_t; + +extern void abort (void); +extern int snprintf (char*, size_t, const char*, ...); + +const char s0[] = ""; +const char s1[] = "a"; +const char s2[] = "ab"; + +extern char ax[]; +extern const char* const ptr; + +#define CAT(x, y) x ## y +#define CONCAT(x, y) CAT (x, y) +#define TEST CONCAT (test_on_line_, __LINE__) + +#define KEEP(expr) do { \ + if ((expr)) { \ + extern void TEST (void); \ + TEST (); \ + } \ + } while (0) + + +void test_literal (int i) +{ + KEEP (0 < snprintf (0, 0, "%s", i ? "" : ax)); + KEEP (1 < snprintf (0, 0, "%s", i ? ax : "1")); + KEEP (2 < snprintf (0, 0, "%s", i ? "12" : ptr)); + + KEEP (1 > snprintf (0, 0, "%s", i ? "" : ax)); + KEEP (1 > snprintf (0, 0, "%s", i ? ax : "1")); + KEEP (2 > snprintf (0, 0, "%s", i ? "12" : ptr)); +} + +void test_cststr (int i) +{ + KEEP (0 < snprintf (0, 0, "%s", i ? s0 : ax)); + KEEP (1 < snprintf (0, 0, "%s", i ? ax : s1)); + KEEP (2 < snprintf (0, 0, "%s", i ? s2 : ptr)); + + KEEP (1 > snprintf (0, 0, "%s", i ? s0 : ax)); + KEEP (1 > snprintf (0, 0, "%s", i ? ax : s1)); + KEEP (2 > snprintf (0, 0, "%s", i ? s2 : ptr)); +} + +/* { dg-final { scan-tree-dump-times "test_on_line_" 12 "optimized" } } */ |