From 665db3aeb48f0f0970bb0e01f37f9fd9fb013ea4 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Wed, 5 Dec 2018 16:10:08 -0700 Subject: [PATCH] re PR c/87028 (false positive -Wstringop-truncation strncpy with global variable source string) PR c/87028 * calls.c (get_attr_nonstring_decl): Avoid setting *REF to SSA_NAME_VAR. * gcc/gimple-low.c (lower_stmt): Fold builtin calls here. * gimplify (maybe_fold_stmt): Avoid folding builtin calls. PR c/87028 * c-c++-common/Wstringop-truncation.c: Remove xfails. * gcc.dg/Wstringop-truncation-5.c: New test. * gcc.dg/strcmpopt_1.c: Adjust. * gcc.dg/tree-ssa/pr79697.c: Same. From-SVN: r266833 --- gcc/ChangeLog | 9 ++ gcc/calls.c | 15 +- gcc/gimple-low.c | 7 + gcc/gimplify.c | 4 + gcc/testsuite/ChangeLog | 8 ++ .../c-c++-common/Wstringop-truncation.c | 7 +- gcc/testsuite/gcc.dg/Wstringop-truncation-5.c | 128 ++++++++++++++++++ gcc/testsuite/gcc.dg/fold-bcopy.c | 8 +- gcc/testsuite/gcc.dg/strcmpopt_1.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/pr79697.c | 4 +- 10 files changed, 179 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wstringop-truncation-5.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 533f1a07b2a..639f5cfd984 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-12-05 Richard Biener + Martin Sebor + + PR c/87028 + * calls.c (get_attr_nonstring_decl): Avoid setting *REF to + SSA_NAME_VAR. + * gcc/gimple-low.c (lower_stmt): Fold builtin calls here. + * gimplify (maybe_fold_stmt): Avoid folding builtin calls. + 2018-12-05 Iain Sandoe * configure.ac (gcc_cv_otool): Set. diff --git a/gcc/calls.c b/gcc/calls.c index 8978d3b42fd..98c6377d78f 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1503,6 +1503,7 @@ tree get_attr_nonstring_decl (tree expr, tree *ref) { tree decl = expr; + tree var = NULL_TREE; if (TREE_CODE (decl) == SSA_NAME) { gimple *def = SSA_NAME_DEF_STMT (decl); @@ -1515,17 +1516,25 @@ get_attr_nonstring_decl (tree expr, tree *ref) || code == VAR_DECL) decl = gimple_assign_rhs1 (def); } - else if (tree var = SSA_NAME_VAR (decl)) - decl = var; + else + var = SSA_NAME_VAR (decl); } if (TREE_CODE (decl) == ADDR_EXPR) decl = TREE_OPERAND (decl, 0); + /* To simplify calling code, store the referenced DECL regardless of + the attribute determined below, but avoid storing the SSA_NAME_VAR + obtained above (it's not useful for dataflow purposes). */ if (ref) *ref = decl; - if (TREE_CODE (decl) == ARRAY_REF) + /* Use the SSA_NAME_VAR that was determined above to see if it's + declared nonstring. Otherwise drill down into the referenced + DECL. */ + if (var) + decl = var; + else if (TREE_CODE (decl) == ARRAY_REF) decl = TREE_OPERAND (decl, 0); else if (TREE_CODE (decl) == COMPONENT_REF) decl = TREE_OPERAND (decl, 1); diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index c3777a1e761..b00e14f6554 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-low.h" #include "predict.h" #include "gimple-predict.h" +#include "gimple-fold.h" /* The differences between High GIMPLE and Low GIMPLE are the following: @@ -378,6 +379,12 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data) gsi_next (gsi); return; } + + /* We delay folding of built calls from gimplification to + here so the IL is in consistent state for the diagnostic + machineries job. */ + if (gimple_call_builtin_p (stmt)) + fold_stmt (gsi); } break; diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 40fbaa2c523..d96ee43e7de 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -3192,6 +3192,10 @@ maybe_fold_stmt (gimple_stmt_iterator *gsi) return false; else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS) return false; + /* Delay folding of builtins until the IL is in consistent state + so the diagnostic machinery can do a better job. */ + if (gimple_call_builtin_p (gsi_stmt (*gsi))) + return false; return fold_stmt (gsi); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 77dbe743406..8bed4b455e0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2018-12-05 Martin Sebor + + PR c/87028 + * c-c++-common/Wstringop-truncation.c: Remove xfails. + * gcc.dg/Wstringop-truncation-5.c: New test. + * gcc.dg/strcmpopt_1.c: Adjust. + * gcc.dg/tree-ssa/pr79697.c: Same. + 2018-12-05 Richard Sandiford PR tree-optimization/88064 diff --git a/gcc/testsuite/c-c++-common/Wstringop-truncation.c b/gcc/testsuite/c-c++-common/Wstringop-truncation.c index e78e85ec870..b85711d6b3f 100644 --- a/gcc/testsuite/c-c++-common/Wstringop-truncation.c +++ b/gcc/testsuite/c-c++-common/Wstringop-truncation.c @@ -329,9 +329,8 @@ void test_strncpy_array (Dest *pd, int i, const char* s) of the array to NUL is not diagnosed. */ { /* This might be better written using memcpy() but it's safe so - it probably shouldn't be diagnosed. It currently triggers - a warning because of bug 81704. */ - strncpy (dst7, "0123456", sizeof dst7); /* { dg-bogus "\\\[-Wstringop-truncation]" "bug 81704" { xfail *-*-* } } */ + it shouldn't be diagnosed. */ + strncpy (dst7, "0123456", sizeof dst7); /* { dg-bogus "\\\[-Wstringop-truncation]" } */ dst7[sizeof dst7 - 1] = '\0'; sink (dst7); } @@ -350,7 +349,7 @@ void test_strncpy_array (Dest *pd, int i, const char* s) } { - strncpy (pd->a5, "01234", sizeof pd->a5); /* { dg-bogus "\\\[-Wstringop-truncation]" "bug 81704" { xfail *-*-* } } */ + strncpy (pd->a5, "01234", sizeof pd->a5); /* { dg-bogus "\\\[-Wstringop-truncation]" } */ pd->a5[sizeof pd->a5 - 1] = '\0'; sink (pd); } diff --git a/gcc/testsuite/gcc.dg/Wstringop-truncation-5.c b/gcc/testsuite/gcc.dg/Wstringop-truncation-5.c new file mode 100644 index 00000000000..dbb5e1fed32 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-truncation-5.c @@ -0,0 +1,128 @@ +/* PR tree-optimization/87028 - false positive -Wstringop-truncation + strncpy with global variable source string + { dg-do compile } + { dg-options "-O2 -Wstringop-truncation" } */ + +char *strncpy (char *, const char *, __SIZE_TYPE__); + +#define STR "1234567890" + +struct S +{ + char a[5], b[5]; +}; + +const char arr[] = STR; +const char* const ptr = STR; + +const char arr2[][10] = { "123", STR }; + +void test_literal (struct S *s) +{ + strncpy (s->a, STR, sizeof s->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */ + s->a[sizeof s->a - 1] = '\0'; +} + +void test_global_arr (struct S *s) +{ + strncpy (s->a, arr, sizeof s->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */ + s->a [sizeof s->a - 1] = '\0'; +} + +void test_global_arr2 (struct S *s) +{ + strncpy (s->a, arr2[1], sizeof s->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */ + s->a [sizeof s->a - 1] = '\0'; + + strncpy (s->b, arr2[0], sizeof s->a - 1); +} + +void test_global_ptr (struct S *s) +{ + strncpy (s->a, ptr, sizeof s->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */ + s->a [sizeof s->a - 1] = '\0'; +} + +void test_local_arr (struct S *s) +{ + const char arr[] = STR; + strncpy (s->a, arr, sizeof s->a - 1); + s->a [sizeof s->a - 1] = '\0'; +} + +void test_local_ptr (struct S *s) +{ + const char* const ptr = STR; + strncpy (s->a, ptr, sizeof s->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */ + s->a [sizeof s->a - 1] = '\0'; +} + +void test_compound_literal (struct S *s) +{ + strncpy (s->a, (char[]){ STR }, sizeof s->a - 1); + s->a [sizeof s->a - 1] = '\0'; +} +/* PR tree-optimization/87028 - false positive -Wstringop-truncation + strncpy with global variable source string + { dg-do compile } + { dg-options "-O2 -Wstringop-truncation" } */ + +char *strncpy (char *, const char *, __SIZE_TYPE__); + +#define STR "1234567890" + +struct S +{ + char a[5], b[5]; +}; + +const char arr[] = STR; +const char* const ptr = STR; + +const char arr2[][10] = { "123", STR }; + +void test_literal (struct S *s) +{ + strncpy (s->a, STR, sizeof s->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */ + s->a[sizeof s->a - 1] = '\0'; +} + +void test_global_arr (struct S *s) +{ + strncpy (s->a, arr, sizeof s->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */ + s->a [sizeof s->a - 1] = '\0'; +} + +void test_global_arr2 (struct S *s) +{ + strncpy (s->a, arr2[1], sizeof s->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */ + s->a [sizeof s->a - 1] = '\0'; + + strncpy (s->b, arr2[0], sizeof s->a - 1); +} + +void test_global_ptr (struct S *s) +{ + strncpy (s->a, ptr, sizeof s->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */ + s->a [sizeof s->a - 1] = '\0'; +} + +void test_local_arr (struct S *s) +{ + const char arr[] = STR; + strncpy (s->a, arr, sizeof s->a - 1); + s->a [sizeof s->a - 1] = '\0'; +} + +void test_local_ptr (struct S *s) +{ + const char* const ptr = STR; + strncpy (s->a, ptr, sizeof s->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */ + s->a [sizeof s->a - 1] = '\0'; +} + +void test_compound_literal (struct S *s) +{ + strncpy (s->a, (char[]){ STR }, sizeof s->a - 1); + s->a [sizeof s->a - 1] = '\0'; +} diff --git a/gcc/testsuite/gcc.dg/fold-bcopy.c b/gcc/testsuite/gcc.dg/fold-bcopy.c index ed6cd060339..9a5448465ee 100644 --- a/gcc/testsuite/gcc.dg/fold-bcopy.c +++ b/gcc/testsuite/gcc.dg/fold-bcopy.c @@ -1,6 +1,6 @@ /* PR tree-optimization/80933 - redundant bzero/bcopy calls not eliminated { dg-do compile } - { dg-options "-O0 -Wall -fdump-tree-gimple" } */ + { dg-options "-O1 -Wall -fdump-tree-lower" } */ void f0 (void *dst, const void *src, unsigned n) { @@ -46,9 +46,9 @@ void f6 (void *p) /* Verify that calls to bcmp, bcopy, and bzero have all been removed and one of each replaced with memcmp, memmove, and memset, respectively. The remaining three should be eliminated. - { dg-final { scan-tree-dump-not "bcmp|bcopy|bzero" "gimple" } } - { dg-final { scan-tree-dump-times "memcmp|memmove|memset" 3 "gimple" } } + { dg-final { scan-tree-dump-not "bcmp|bcopy|bzero" "lower" } } + { dg-final { scan-tree-dump-times "memcmp|memmove|memset" 3 "lower" } } Verify that the bcopy to memmove transformation correctly transposed the source and destination pointer arguments. - { dg-final { scan-tree-dump-times "memmove \\(dst, src" 1 "gimple" } } */ + { dg-final { scan-tree-dump-times "memmove \\(dst, src" 1 "lower" } } */ diff --git a/gcc/testsuite/gcc.dg/strcmpopt_1.c b/gcc/testsuite/gcc.dg/strcmpopt_1.c index 40596a20b40..b1e0bc3b274 100644 --- a/gcc/testsuite/gcc.dg/strcmpopt_1.c +++ b/gcc/testsuite/gcc.dg/strcmpopt_1.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-fdump-tree-gimple" } */ +/* { dg-options "-fdump-tree-lower" } */ #include #include @@ -25,4 +25,4 @@ int main () return 0; } -/* { dg-final { scan-tree-dump-times "strcmp \\(" 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "strcmp \\(" 2 "lower" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr79697.c b/gcc/testsuite/gcc.dg/tree-ssa/pr79697.c index fc3580e3ce3..973ec0dc193 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr79697.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr79697.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-gimple -fdump-tree-cddce-details -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fdump-tree-lower -fdump-tree-cddce-details -fdump-tree-optimized" } */ void f(void) { @@ -18,4 +18,4 @@ void h(void) /* { dg-final { scan-tree-dump "Deleting : __builtin_strdup" "cddce1" } } */ /* { dg-final { scan-tree-dump "Deleting : __builtin_strndup" "cddce1" } } */ -/* { dg-final { scan-tree-dump "__builtin_malloc" "gimple" } } */ +/* { dg-final { scan-tree-dump "__builtin_malloc" "lower" } } */ -- 2.30.2