public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [PATCH] look harder for MEM_REF operand equality to avoid -Wstringop-truncation (PR 84561)
@ 2018-09-15  8:43 Bernd Edlinger
  2018-09-17 17:34 ` Jeff Law
  0 siblings, 1 reply; 26+ messages in thread
From: Bernd Edlinger @ 2018-09-15  8:43 UTC (permalink / raw)
  To: Martin Sebor; +Cc: Jeff Law, Richard Biener, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1691 bytes --]

On 9/14/18, Martin Sebor wrote:
> As I said above, this happens during the dom walk in the ccp
> pass:
> 
>   substitute_and_fold_dom_walker walker (CDI_DOMINATORS, this);
>   walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
> 
> The warning is issued during the walker.walk() call as
> strncpy is being folded into memcpy.  The prior assignments are
> only propagated later, when the next statement after the strncpy
> call is reached.  It happens in
> substitute_and_fold_dom_walker::before_dom_children(). So during
> the strncpy folding we see the next statement as:
> 
>   MEM[(struct S *)_1].a[n_7] = 0;
> 
> After the strncpy call is transformed to memcpy, the assignment
> above is transformed to
> 
>   MEM[(struct S *)_8].a[3] = 0;
> 
> 
>>     If they're only discovered as copies within the pass where you're trying
>>     to issue the diagnostic, then you'd want to see if the pass has any
>>     internal structures that tell you about equivalences.
> 
> 
> I don't know if this is possible.  I don't see any APIs in
> tree-ssa-propagate.h that would let me query the internal data
> somehow to find out during folding (when the warning is issued).


Well,

if I see this right, the CCP is doing tree transformations
while from the folding of strncpy the predicate maybe_diag_stxncpy_trunc
is called, and sees inconsistent information, in the tree,
and therefore it issues a warning.

I understand that walking the references is fragile at least
in this state.

But why not just prevent warnings when this is called from CCP?


Like this?

Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
Is it OK for trunk?


Thanks
Bernd.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch-pr84561.diff --]
[-- Type: text/x-patch; name="patch-pr84561.diff", Size: 2414 bytes --]

gcc:
2018-09-15  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	PR tree-optimization/84561
	* tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Bail out if called
	from CCP.

testsuite:
2018-09-15  Martin Sebor  <msebor@redhat.com>

	PR tree-optimization/84561
	* gcc.dg/Wstringop-truncation-6.c: New test.

diff -Npur gcc/tree-ssa-strlen.c gcc/tree-ssa-strlen.c
--- gcc/tree-ssa-strlen.c	2018-09-14 13:12:10.000000000 +0200
+++ gcc/tree-ssa-strlen.c	2018-09-15 08:04:57.011142267 +0200
@@ -1846,11 +1846,13 @@ is_strlen_related_p (tree src, tree len)
 bool
 maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
 {
+  wide_int cntrange[2];
   gimple *stmt = gsi_stmt (gsi);
   if (gimple_no_warning_p (stmt))
     return false;
 
-  wide_int cntrange[2];
+  if (current_pass && !strcmp (current_pass->name, "ccp"))
+    return false;
 
   if (TREE_CODE (cnt) == INTEGER_CST)
     cntrange[0] = cntrange[1] = wi::to_wide (cnt);
diff -Npur gcc/testsuite/gcc.dg/Wstringop-truncation-6.c gcc/testsuite/gcc.dg/Wstringop-truncation-6.c
--- gcc/testsuite/gcc.dg/Wstringop-truncation-6.c	1970-01-01 01:00:00.000000000 +0100
+++ gcc/testsuite/gcc.dg/Wstringop-truncation-6.c	2018-09-15 08:02:35.597198845 +0200
@@ -0,0 +1,59 @@
+/* PR tree-optimization/84561 - -Wstringop-truncation with -O2 depends
+   on strncpy's size type
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+enum { N = 3 };
+
+struct S
+{
+  char a[N + 1];
+};
+
+void set (struct S *ps, const char* s, size_t n)
+{
+  if (n > N)
+    n = N;
+
+  __builtin_strncpy (ps->a, s, n);   /* { dg-bogus "\\\[-Wstringop-truncation]" } */
+  ps->a[n] = 0;
+}
+
+struct A
+{
+  struct S str;
+};
+
+void setStringSize_t (struct A *pa, const char *s, size_t n)
+{
+  set (&pa->str, s, n);
+}
+
+void setStringUnsignedInt (struct A *pa, const char* s, unsigned int n)
+{
+  set (&pa->str, s, n);
+}
+
+struct B
+{
+  struct A a;
+};
+
+struct A* getA (struct B *pb)
+{
+  return &pb->a;
+}
+
+void f (struct A *pa)
+{
+  setStringUnsignedInt (pa, "123", N); // No warning here.
+  setStringSize_t (pa, "123", N);      // No warning here.
+}
+
+void g (struct B *pb)
+{
+  setStringUnsignedInt (getA (pb), "123", N);  // Unexpected warning here.
+  setStringSize_t (getA (pb), "123", N);       // No warning here.
+}

^ permalink raw reply	[flat|nested] 26+ messages in thread
* [PATCH] look harder for MEM_REF operand equality to avoid -Wstringop-truncation (PR 84561)
@ 2018-08-30  0:12 Martin Sebor
  2018-08-30  8:35 ` Richard Biener
  0 siblings, 1 reply; 26+ messages in thread
From: Martin Sebor @ 2018-08-30  0:12 UTC (permalink / raw)
  To: Gcc Patch List

[-- Attachment #1: Type: text/plain, Size: 632 bytes --]

The attached patch adds code to work harder to determine whether
the destination of an assignment involving MEM_REF is the same
as the destination of a prior strncpy call.  The included test
case demonstrates when this situation comes up.  During ccp,
dstbase and lhsbase returned by get_addr_base_and_unit_offset()
end up looking like this:

   _8 = &pb_3(D)->a;
   _9 = _8;
   _1 = _9;
   strncpy (MEM_REF (&pb_3(D)->a), ...);
   MEM[(struct S *)_1].a[n_7] = 0;

so the loops follow the simple assignments until we get at
the ADDR_EXPR assigned to _8 which is the same as the strncpy
destination.

Tested on x86_64-linux.

Martin

[-- Attachment #2: gcc-84561.diff --]
[-- Type: text/x-patch, Size: 3278 bytes --]

PR tree-optimization/84561 - -Wstringop-truncation with -O2 depends on strncpy's size type

gcc/ChangeLog:

	PR tree-optimization/84561
	* tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Look harder for
	MEM_REF operand equality.

gcc/testsuite/ChangeLog:

	PR tree-optimization/84561
	* gcc.dg/Wstringop-truncation-6.c: New test.

Index: gcc/tree-ssa-strlen.c
===================================================================
--- gcc/tree-ssa-strlen.c	(revision 263965)
+++ gcc/tree-ssa-strlen.c	(working copy)
@@ -1978,11 +1978,43 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi
 
       poly_int64 lhsoff;
       tree lhsbase = get_addr_base_and_unit_offset (lhs, &lhsoff);
-      if (lhsbase
-	  && dstbase
-	  && known_eq (dstoff, lhsoff)
-	  && operand_equal_p (dstbase, lhsbase, 0))
+      bool eqloff = lhsbase && dstbase && known_eq (dstoff, lhsoff);
+
+      if (eqloff && operand_equal_p (dstbase, lhsbase, 0))
 	return false;
+
+      if (eqloff
+	  && TREE_CODE (dstbase) == MEM_REF
+	  && TREE_CODE (lhsbase) == MEM_REF
+	  && tree_int_cst_equal (TREE_OPERAND (dstbase, 1),
+				 TREE_OPERAND (lhsbase, 1)))
+	{
+	  /* For MEM_REFs with the same offset follow the chain of
+	     SSA_NAME assignments to their source and compare those
+	     for equality.  */
+	  dstbase = TREE_OPERAND (dstbase, 0);
+	  while (TREE_CODE (dstbase) == SSA_NAME)
+	    {
+	      gimple *def = SSA_NAME_DEF_STMT (dstbase);
+	      if (gimple_assign_single_p (def))
+		dstbase = gimple_assign_rhs1 (def);
+	      else
+		break;
+	    }
+
+	  lhsbase = TREE_OPERAND (lhsbase, 0);
+	  while (TREE_CODE (lhsbase) == SSA_NAME)
+	    {
+	      gimple *def = SSA_NAME_DEF_STMT (lhsbase);
+	      if (gimple_assign_single_p (def))
+		lhsbase = gimple_assign_rhs1 (def);
+	      else
+		break;
+	    }
+
+	  if (operand_equal_p (dstbase, lhsbase, 0))
+	    return false;
+	}
     }
 
   int prec = TYPE_PRECISION (TREE_TYPE (cnt));
Index: gcc/testsuite/gcc.dg/Wstringop-truncation-6.c
===================================================================
--- gcc/testsuite/gcc.dg/Wstringop-truncation-6.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/Wstringop-truncation-6.c	(working copy)
@@ -0,0 +1,59 @@
+/* PR tree-optimization/84561 - -Wstringop-truncation with -O2 depends
+   on strncpy's size type
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+enum { N = 3 };
+
+struct S
+{
+  char a[N + 1];
+};
+
+void set (struct S *ps, const char* s, size_t n)
+{
+  if (n > N)
+    n = N;
+
+  __builtin_strncpy (ps->a, s, n);   /* { dg-bogus "\\\[-Wstringop-truncation]" } */
+  ps->a[n] = 0;
+}
+
+struct A
+{
+  struct S str;
+};
+
+void setStringSize_t (struct A *pa, const char *s, size_t n)
+{
+  set (&pa->str, s, n);
+}
+
+void setStringUnsignedInt (struct A *pa, const char* s, unsigned int n)
+{
+  set (&pa->str, s, n);
+}
+
+struct B
+{
+  struct A a;
+};
+
+struct A* getA (struct B *pb)
+{
+  return &pb->a;
+}
+
+void f (struct A *pa)
+{
+  setStringUnsignedInt (pa, "123", N); // No warning here.
+  setStringSize_t (pa, "123", N);      // No warning here.
+}
+
+void g (struct B *pb)
+{
+  setStringUnsignedInt (getA (pb), "123", N);  // Unexpected warning here.
+  setStringSize_t (getA (pb), "123", N);       // No warning here.
+}

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2018-10-04  3:02 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-15  8:43 [PATCH] look harder for MEM_REF operand equality to avoid -Wstringop-truncation (PR 84561) Bernd Edlinger
2018-09-17 17:34 ` Jeff Law
2018-09-17 17:50   ` Richard Biener
2018-09-17 18:41     ` Bernd Edlinger
2018-09-17 21:18     ` Martin Sebor
2018-09-18  0:17       ` Jeff Law
2018-09-18  2:49         ` Martin Sebor
  -- strict thread matches above, loose matches on Subject: below --
2018-08-30  0:12 Martin Sebor
2018-08-30  8:35 ` Richard Biener
2018-08-30 16:54   ` Martin Sebor
2018-08-30 17:22     ` Richard Biener
2018-08-30 17:39       ` Martin Sebor
2018-08-31 10:07         ` Richard Biener
2018-09-12 18:03           ` Martin Sebor
2018-09-14 21:35             ` Jeff Law
2018-09-14 23:44               ` Martin Sebor
2018-09-17 23:13                 ` Jeff Law
2018-09-18 17:38                   ` Martin Sebor
2018-09-18 19:24                     ` Jeff Law
2018-09-18 20:01                       ` Martin Sebor
2018-09-19  5:40                         ` Jeff Law
2018-09-19 14:31                           ` Martin Sebor
2018-09-20  9:21                             ` Richard Biener
2018-09-21 14:50                               ` Martin Sebor
2018-10-04  3:08                             ` Jeff Law
2018-09-19 13:51                       ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).