From bb0f14ae684a38a44aaf42b312c213aedaa74103 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 12 Jun 2018 17:14:31 +0000 Subject: [PATCH] PR c/85931 - -Wsizeof-pointer-memaccess for strncpy with size of source gcc/c-family/ChangeLog: PR c/85931 * c-warn.c (sizeof_pointer_memaccess_warning): Avoid warning when sizeof source and destination yields the same value. gcc/ChangeLog: PR c/85931 * fold-const.c (operand_equal_p): Handle SAVE_EXPR. gcc/testsuite/ChangeLog: PR c/85931 * gcc.dg/Wstringop-truncation-3.c: New test. From-SVN: r261515 --- gcc/ChangeLog | 5 ++ gcc/c-family/ChangeLog | 6 ++ gcc/c-family/c-warn.c | 17 +++++- gcc/fold-const.c | 1 + gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/Wstringop-truncation-3.c | 59 +++++++++++++++++++ 6 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wstringop-truncation-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 48d6d8307b1..b1b32998fde 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2018-06-12 Martin Sebor + + PR c/85931 + * fold-const.c (operand_equal_p): Handle SAVE_EXPR. + 2018-06-12 Will Schmidt * config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Add diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 9ef0a12eb6a..f63af26624c 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2018-06-12 Martin Sebor + + PR c/85931 + * c-warn.c (sizeof_pointer_memaccess_warning): Avoid warning when + sizeof source and destination yields the same value. + 2018-06-12 Martin Liska * c.opt: Make MPX-related options as Deprecated. diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index 859d72b3f83..95ac09d76a1 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -792,13 +792,26 @@ sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee, { /* The argument type may be an array. Diagnose bounded string copy functions that specify the bound in terms of the source - argument rather than the destination. */ + argument rather than the destination unless they are equal + to one another. Handle constant sizes and also try to handle + sizeof expressions involving VLAs. */ if (strop && !cmp && fncode != BUILT_IN_STRNDUP && src) { tem = tree_strip_nop_conversions (src); if (TREE_CODE (tem) == ADDR_EXPR) tem = TREE_OPERAND (tem, 0); - if (operand_equal_p (tem, sizeof_arg[idx], OEP_ADDRESS_OF)) + + tree d = tree_strip_nop_conversions (dest); + if (TREE_CODE (d) == ADDR_EXPR) + d = TREE_OPERAND (d, 0); + + tree dstsz = TYPE_SIZE_UNIT (TREE_TYPE (d)); + tree srcsz = TYPE_SIZE_UNIT (TREE_TYPE (tem)); + + if ((!dstsz + || !srcsz + || !operand_equal_p (dstsz, srcsz, OEP_LEXICOGRAPHIC)) + && operand_equal_p (tem, sizeof_arg[idx], OEP_ADDRESS_OF)) warning_at (sizeof_arg_loc[idx], OPT_Wsizeof_pointer_memaccess, "argument to % in %qD call is the same " "expression as the source; did you mean to use " diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 1e8d79e4022..c85a9912435 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -3358,6 +3358,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) case CLEANUP_POINT_EXPR: case EXPR_STMT: + case SAVE_EXPR: if (flags & OEP_LEXICOGRAPHIC) return OP_SAME (0); return 0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 088f5c2ff7f..f9c8d93d3d3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-06-12 Martin Sebor + + PR c/85931 + * gcc.dg/Wstringop-truncation-3.c: New test. + 2018-06-12 Will Schmidt * gcc.target/powerpc/p8-vec-xl-xst-v2.c: New. diff --git a/gcc/testsuite/gcc.dg/Wstringop-truncation-3.c b/gcc/testsuite/gcc.dg/Wstringop-truncation-3.c new file mode 100644 index 00000000000..57f4d64188a --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-truncation-3.c @@ -0,0 +1,59 @@ +/* PR c/85931 - -Wsizeof-pointer-memaccess for strncpy with size of source + { dg-do compile } + { dg-options "-O2 -Wall -Wstringop-truncation -ftrack-macro-expansion=0" } */ + +typedef __SIZE_TYPE__ size_t; + +extern char* strncpy (char*, const char*, size_t); + +extern char a3[3], b3[3]; +extern char a5[5], b5[5]; +extern char ax[], bx[]; + +struct SA +{ + char a3[3], b3[3]; + char a5[5], b5[5]; + char ax[]; +}; + +void sink (void*, ...); + +#define T(d, s, n) sink (strncpy (d, s, n)) + +void test_array (unsigned n) +{ + T (a3, b3, 3); + /* For the following statemenmt, GCC 8.1 issues warning: + + argument to ‘sizeof’ in ‘strncpy’ call is the same expression + as the source; did you mean to use the size of the destination? + + Since the size of both the source and destination the warning + isn't helpful. Verify that it isn't issued. */ + T (a3, b3, sizeof b3); /* { dg-bogus "\\\[-Wsizeof-pointer-memaccess" } */ + + T (a3, ax, sizeof a3); /* { dg-warning "\\\[-Wstringop-truncation" } */ + T (ax, a3, sizeof a3); /* { dg-warning "argument to .sizeof. in .strncpy. call is the same expression as the source" } */ + + char an[n], bn[n]; + sink (an, bn); + + T (an, bn, sizeof bn); /* { dg-bogus "\\\[-Wsizeof-pointer-memaccess" } */ +} + +void test_member_array (struct SA *sa, unsigned n) +{ + T (sa->a3, sa->b3, 3); + T (sa->a3, sa->b3, sizeof sa->b3); /* { dg-bogus "\\\[-Wsizeof-pointer-memaccess" } */ + + T (sa->a3, sa->ax, sizeof sa->a3); /* { dg-warning "\\\[-Wstringop-truncation" } */ + T (sa->ax, sa->a3, sizeof sa->a3); /* { dg-warning "argument to .sizeof. in .strncpy. call is the same expression as the source" } */ + + struct VarLenStruct { + char an[n], bn[n]; + } x; + + sink (&x); + T (x.an, x.bn, sizeof x.bn); /* { dg-bogus "\\\[-Wsizeof-pointer-memaccess" } */ +} -- 2.30.2