public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "msebor at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug sanitizer/99673] [11 Regression] bogus -Wstringop-overread warning with address sanitizer due to member address substitution
Date: Fri, 19 Mar 2021 21:44:07 +0000	[thread overview]
Message-ID: <bug-99673-4-0bt1L3n84v@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-99673-4@http.gcc.gnu.org/bugzilla/>

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99673

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to fail|                            |11.0
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
                 CC|                            |msebor at gcc dot gnu.org
   Last reconfirmed|                            |2021-03-19
            Summary|[11 Regression] bogus       |[11 Regression] bogus
                   |-Wstringop-overread warning |-Wstringop-overread warning
                   |with address sanitizer      |with address sanitizer due
                   |                            |to member address
                   |                            |substitution

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
A further reduced/simplified test case is below.  The root cause is similar to
the one discussed in pr99578 comment 8.

$ cat pr99673.c && gcc -Os -S -Wall -fsanitize=address
-fno-inline-functions-called-once -m32 pr99673.c
struct B {
  int i;
  struct A {
    short sa[8];
  } a[2];
};

struct C {
  char n, ax[];
};

struct D { int i, j, k; };

int f (const short[8]);

void g (struct C *pc, struct D *pd, int i)
{
  struct B *pb = (void *)pc->ax;
  pd->i = pb->i;

  const short *psa = pb->a[i].sa;
  if (f (psa))
    return;
}
pr99673.c: In function ‘g’:
pr99673.c:22:7: warning: ‘f’ reading 16 bytes from a region of size 4
[-Wstringop-overread]
   22 |   if (f (psa))
      |       ^~~~~~~
pr99673.c:22:7: note: referencing argument 1 of type ‘const short int *’
pr99673.c:14:5: note: in a call to function ‘f’
   14 | int f (const short[8]);
      |     ^

The output of -fdump-tree-optimized shows what triggers the warning.  The
difference between the case discussed in pr99578 comment 8 and this is here
that it's the sanopt pass that replaces the pb->a[i].sa as the argument to f()
with the address of pc->i plus some offset.  pc->i is a 4-byte int, which is
where the 4 bytes in the warning comes from.

;; Function g (g, funcdef_no=0, decl_uid=2314, cgraph_uid=1, symbol_order=0)

void g (struct C * pc, struct D * pd, int i)
{
  const short int * psa;
  int _1;
  sizetype _9;
  sizetype _10;
  sizetype _11;
  unsigned int _12;
  int * _13;
  int * _14;
  unsigned int _17;
  unsigned int _18;
  signed char * _19;
  signed char _20;
  _Bool _21;
  unsigned int _22;
  signed char _23;
  signed char _24;
  _Bool _25;
  _Bool _26;
  unsigned int _27;
  unsigned int _28;
  unsigned int _29;
  signed char * _30;
  signed char _31;
  _Bool _32;
  unsigned int _33;
  signed char _34;
  signed char _35;
  _Bool _36;
  _Bool _37;

  <bb 2> [local count: 1073741824]:
  _13 = &MEM[(struct B *)pc_2(D) + 1B].i;   <<< address of pc.i
  _12 = (unsigned int) _13;
  _17 = _12 >> 3;
  _18 = _17 + 536870912;
  _19 = (signed char *) _18;
  _20 = *_19;
  _21 = _20 != 0;
  _22 = _12 & 7;
  _23 = (signed char) _22;
  _24 = _23 + 3;
  _25 = _24 >= _20;
  _26 = _21 & _25;
  if (_26 != 0)
    goto <bb 3>; [0.05%]
  else
    goto <bb 4>; [99.95%]

  <bb 3> [local count: 536864]:
  __builtin___asan_report_load4 (_12);

  <bb 4> [local count: 1073741824]:
  _1 = MEM[(struct B *)pc_2(D) + 1B].i;
  _14 = &pd_4(D)->i;
  _27 = (unsigned int) _14;
  _28 = _27 >> 3;
  _29 = _28 + 536870912;
  _30 = (signed char *) _29;
  _31 = *_30;
  _32 = _31 != 0;
  _33 = _27 & 7;
  _34 = (signed char) _33;
  _35 = _34 + 3;
  _36 = _35 >= _31;
  _37 = _32 & _36;
  if (_37 != 0)
    goto <bb 5>; [0.05%]
  else
    goto <bb 6>; [99.95%]

  <bb 5> [local count: 536864]:
  __builtin___asan_report_store4 (_27);

  <bb 6> [local count: 1073741824]:
  pd_4(D)->i = _1;
  _9 = (sizetype) i_6(D);
  _10 = _9 * 16;
  _11 = _10 + 4;
  psa_7 = _13 + _11;                        <<< &pc.i + (i * 16) + 4
  f (psa_7); [tail call]
  return;

}

The output below shows the difference between the last "good" IL and the "bad"
IL introduced by the sanopt transformation.  To avoid the warning either the
sanopt pass will need to be changed to avoid this substitution or to annotate
it somehow so the warning knows not to trigger.

--- pr99673.c.184t.slsr 2021-03-19 15:21:31.134229177 -0600
+++ pr99673.c.239t.sanopt       2021-03-19 15:21:31.135229188 -0600
@@ -1,13 +1,14 @@

 ;; Function g (g, funcdef_no=0, decl_uid=2314, cgraph_uid=1, symbol_order=0)

-;; 1 loops found
-;;
-;; Loop 0
-;;  header 0, latch 1
-;;  depth 0, outer -1
-;;  nodes: 0 1 2
-;; 2 succs { 1 }
+
+Symbols to be put in SSA form
+{ D.2322 }
+Incremental SSA update started at block: 0
+Number of blocks in CFG: 7
+Number of blocks to update: 6 ( 86%)
+
+
 void g (struct C * pc, struct D * pd, int i)
 {
   const short int * psa;
@@ -15,23 +16,81 @@
   sizetype _9;
   sizetype _10;
   sizetype _11;
-  struct B * _12;
+  unsigned int _12;
   int * _13;
   int * _14;
+  unsigned int _17;
+  unsigned int _18;
+  signed char * _19;
+  signed char _20;
+  _Bool _21;
+  unsigned int _22;
+  signed char _23;
+  signed char _24;
+  _Bool _25;
+  _Bool _26;
+  unsigned int _27;
+  unsigned int _28;
+  unsigned int _29;
+  signed char * _30;
+  signed char _31;
+  _Bool _32;
+  unsigned int _33;
+  signed char _34;
+  signed char _35;
+  _Bool _36;
+  _Bool _37;

   <bb 2> [local count: 1073741824]:
   _13 = &MEM[(struct B *)pc_2(D) + 1B].i;
-  .ASAN_CHECK (6, _13, 4, 4);
+  _12 = (unsigned int) _13;
+  _17 = _12 >> 3;
+  _18 = _17 + 536870912;
+  _19 = (signed char *) _18;
+  _20 = *_19;
+  _21 = _20 != 0;
+  _22 = _12 & 7;
+  _23 = (signed char) _22;
+  _24 = _23 + 3;
+  _25 = _24 >= _20;
+  _26 = _21 & _25;
+  if (_26 != 0)
+    goto <bb 4>; [0.05%]
+  else
+    goto <bb 3>; [99.95%]
+
+  <bb 4> [local count: 536864]:
+  __builtin___asan_report_load4 (_12);
+
+  <bb 3> [local count: 1073741824]:
   _1 = MEM[(struct B *)pc_2(D) + 1B].i;
   _14 = &pd_4(D)->i;
-  .ASAN_CHECK (7, _14, 4, 4);
+  _27 = (unsigned int) _14;
+  _28 = _27 >> 3;
+  _29 = _28 + 536870912;
+  _30 = (signed char *) _29;
+  _31 = *_30;
+  _32 = _31 != 0;
+  _33 = _27 & 7;
+  _34 = (signed char) _33;
+  _35 = _34 + 3;
+  _36 = _35 >= _31;
+  _37 = _32 & _36;
+  if (_37 != 0)
+    goto <bb 6>; [0.05%]
+  else
+    goto <bb 5>; [99.95%]
+
+  <bb 6> [local count: 536864]:
+  __builtin___asan_report_store4 (_27);
+
+  <bb 5> [local count: 1073741824]:
   pd_4(D)->i = _1;
   _9 = (sizetype) i_6(D);
   _10 = _9 * 16;
   _11 = _10 + 4;
-  _12 = &MEM[(struct B *)pc_2(D) + 1B];
-  psa_7 = _12 + _11;
-  f (psa_7);
+  psa_7 = _13 + _11;
+  f (psa_7); [tail call]
   return;

 }

  reply	other threads:[~2021-03-19 21:44 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-19 16:59 [Bug sanitizer/99673] New: [11 Regression] bogus -Wstringop-overread warning with address sanitizer arnd at linaro dot org
2021-03-19 21:44 ` msebor at gcc dot gnu.org [this message]
2021-03-20 12:22 ` [Bug sanitizer/99673] [11 Regression] bogus -Wstringop-overread warning with address sanitizer due to member address substitution arnd at linaro dot org
2021-03-21 19:06 ` msebor at gcc dot gnu.org
2021-03-22  8:51 ` rguenth at gcc dot gnu.org
2021-03-22 16:07 ` arnd at linaro dot org
2021-04-08 13:09 ` rguenth at gcc dot gnu.org
2021-04-27 11:40 ` [Bug sanitizer/99673] [11/12 " jakub at gcc dot gnu.org
2021-07-28  7:06 ` rguenth at gcc dot gnu.org
2022-01-21 12:50 ` [Bug sanitizer/99673] [11 " rguenth at gcc dot gnu.org
2022-01-21 12:59 ` cvs-commit at gcc dot gnu.org
2022-01-21 13:42 ` marxin at gcc dot gnu.org
2022-04-21  7:48 ` rguenth at gcc dot gnu.org
2022-05-05 12:42 ` [Bug sanitizer/99673] [11/13 " rguenth at gcc dot gnu.org
2023-05-29 10:04 ` [Bug sanitizer/99673] [11/13/14 " jakub at gcc dot gnu.org
2024-03-27  7:37 ` pinskia at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-99673-4-0bt1L3n84v@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).