From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 7C6FA3857C73; Fri, 19 Mar 2021 21:44:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7C6FA3857C73 From: "msebor at gcc dot 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 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: sanitizer X-Bugzilla-Version: 11.0 X-Bugzilla-Keywords: diagnostic X-Bugzilla-Severity: normal X-Bugzilla-Who: msebor at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: cf_known_to_fail bug_status everconfirmed cc cf_reconfirmed_on short_desc Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 19 Mar 2021 21:44:07 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D99673 Martin Sebor 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 --- 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=3Daddress -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 =3D (void *)pc->ax; pd->i =3D pb->i; const short *psa =3D pb->a[i].sa; if (f (psa)) return; } pr99673.c: In function =E2=80=98g=E2=80=99: pr99673.c:22:7: warning: =E2=80=98f=E2=80=99 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 =E2=80=98const short i= nt *=E2=80=99 pr99673.c:14:5: note: in a call to function =E2=80=98f=E2=80=99 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=3D0, decl_uid=3D2314, cgraph_uid=3D1, symbol_o= rder=3D0) 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; [local count: 1073741824]: _13 =3D &MEM[(struct B *)pc_2(D) + 1B].i; <<< address of pc.i _12 =3D (unsigned int) _13; _17 =3D _12 >> 3; _18 =3D _17 + 536870912; _19 =3D (signed char *) _18; _20 =3D *_19; _21 =3D _20 !=3D 0; _22 =3D _12 & 7; _23 =3D (signed char) _22; _24 =3D _23 + 3; _25 =3D _24 >=3D _20; _26 =3D _21 & _25; if (_26 !=3D 0) goto ; [0.05%] else goto ; [99.95%] [local count: 536864]: __builtin___asan_report_load4 (_12); [local count: 1073741824]: _1 =3D MEM[(struct B *)pc_2(D) + 1B].i; _14 =3D &pd_4(D)->i; _27 =3D (unsigned int) _14; _28 =3D _27 >> 3; _29 =3D _28 + 536870912; _30 =3D (signed char *) _29; _31 =3D *_30; _32 =3D _31 !=3D 0; _33 =3D _27 & 7; _34 =3D (signed char) _33; _35 =3D _34 + 3; _36 =3D _35 >=3D _31; _37 =3D _32 & _36; if (_37 !=3D 0) goto ; [0.05%] else goto ; [99.95%] [local count: 536864]: __builtin___asan_report_store4 (_27); [local count: 1073741824]: pd_4(D)->i =3D _1; _9 =3D (sizetype) i_6(D); _10 =3D _9 * 16; _11 =3D _10 + 4; psa_7 =3D _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 "b= ad" 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 annota= te 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=3D0, decl_uid=3D2314, cgraph_uid=3D1, symbol_= order=3D0) -;; 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; [local count: 1073741824]: _13 =3D &MEM[(struct B *)pc_2(D) + 1B].i; - .ASAN_CHECK (6, _13, 4, 4); + _12 =3D (unsigned int) _13; + _17 =3D _12 >> 3; + _18 =3D _17 + 536870912; + _19 =3D (signed char *) _18; + _20 =3D *_19; + _21 =3D _20 !=3D 0; + _22 =3D _12 & 7; + _23 =3D (signed char) _22; + _24 =3D _23 + 3; + _25 =3D _24 >=3D _20; + _26 =3D _21 & _25; + if (_26 !=3D 0) + goto ; [0.05%] + else + goto ; [99.95%] + + [local count: 536864]: + __builtin___asan_report_load4 (_12); + + [local count: 1073741824]: _1 =3D MEM[(struct B *)pc_2(D) + 1B].i; _14 =3D &pd_4(D)->i; - .ASAN_CHECK (7, _14, 4, 4); + _27 =3D (unsigned int) _14; + _28 =3D _27 >> 3; + _29 =3D _28 + 536870912; + _30 =3D (signed char *) _29; + _31 =3D *_30; + _32 =3D _31 !=3D 0; + _33 =3D _27 & 7; + _34 =3D (signed char) _33; + _35 =3D _34 + 3; + _36 =3D _35 >=3D _31; + _37 =3D _32 & _36; + if (_37 !=3D 0) + goto ; [0.05%] + else + goto ; [99.95%] + + [local count: 536864]: + __builtin___asan_report_store4 (_27); + + [local count: 1073741824]: pd_4(D)->i =3D _1; _9 =3D (sizetype) i_6(D); _10 =3D _9 * 16; _11 =3D _10 + 4; - _12 =3D &MEM[(struct B *)pc_2(D) + 1B]; - psa_7 =3D _12 + _11; - f (psa_7); + psa_7 =3D _13 + _11; + f (psa_7); [tail call] return; }=