From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 501C73855145; Fri, 25 Nov 2022 12:36:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 501C73855145 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1669379776; bh=lLBZmkWX2v0z8mMza6yZbxQJxN65zlOZ3fbiONvgX0c=; h=From:To:Subject:Date:In-Reply-To:References:From; b=U3Amyxxn6/Lx9CIwhaem64ohSExsuNqaft0YP5yNRX1+k+e3vO8SU15g/OZHwCupr Ky1RqhWDfz1XA0RJ8GXqOqeAxQvOApBKx4tK/nstyyiVBfM0SHxQkF6hrtB2yT0gl5 AEIgxb/zshky//XBJdiX+vYSfsFi69Rxo2orIgZU= From: "rguenth at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug sanitizer/107866] [12/13 Regression] gcc trunk's UBSan misses a Null-pointer-dereference at -O3. Date: Fri, 25 Nov 2022 12:36:15 +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: 13.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: rguenth at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 12.3 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: 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 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D107866 --- Comment #3 from Richard Biener --- For some reason we think that the .UBSAN_NULL call doesn't clobber the load from nullptr: [local count: 118111600]: + # VUSE <.MEM_3(D)> + pretmp_7 =3D MEM[(int *)0B]; [local count: 1073741824]: - # .MEM_2 =3D PHI <.MEM_3(D)(2), .MEM_6(5)> + # .MEM_2 =3D PHI <.MEM_3(D)(2), .MEM_6(3)> # .MEM_4 =3D VDEF <.MEM_2> a =3D 0B; # .MEM_6 =3D VDEF <.MEM_4> # USE =3D nonlocal escaped=20 # CLB =3D nonlocal escaped=20 .UBSAN_NULL (0B, 0B, 4); - # VUSE <.MEM_6> - _1 =3D MEM[(int *)0B]; - if (_1 !=3D 0) + if (pretmp_7 !=3D 0) that's because DEF_INTERNAL_FN (UBSAN_NULL, ECF_LEAF | ECF_NOTHROW, ". R . ") and thus .UBSAN_NULL only _reads_ from the first argument passed (but also possibly constant NULL(?) valued operands are considered special). The same happens at -O2 btw. At -O1 we eliminate the load. Ah, and call_may_clobber_ref_p_1 has if (gimple_call_internal_p (call)) switch (auto fn =3D gimple_call_internal_fn (call)) { /* Treat these internal calls like ECF_PURE for aliasing, they don't write to any memory the program should care about. They have important other side-effects, and read memory, so can't be ECF_NOVOPS. */ case IFN_UBSAN_NULL: case IFN_UBSAN_BOUNDS: case IFN_UBSAN_VPTR: case IFN_UBSAN_OBJECT_SIZE: case IFN_UBSAN_PTR: case IFN_ASAN_CHECK: return false; so they are not a barrier for the motion of loads which is what happens here. Note that only at -O3 we keep the trapping load because we fail to eliminate the conditional there and have [local count: 118111600]: # VUSE <.MEM_3(D)> pretmp_7 =3D MEM[(int *)0B]; if (pretmp_7 !=3D 0) goto ; [11.00%] else goto ; [89.00%] [local count: 955630224]: # .MEM_1 =3D PHI <.MEM_3(D)(2)> # .MEM_8 =3D VDEF <.MEM_1> a =3D 0B; # .MEM_11 =3D VDEF <.MEM_8> # USE =3D anything # CLB =3D anything __builtin___ubsan_handle_type_mismatch_v1_abort (&*.Lubsan_data0, 0); [local count: 118111600]: # .MEM_4 =3D VDEF <.MEM_3(D)> a =3D 0B; # .MEM_10 =3D VDEF <.MEM_4> # USE =3D anything # CLB =3D anything __builtin___ubsan_handle_type_mismatch_v1_abort (&*.Lubsan_data1, 0); in the end.=