From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 9293D3858D39; Tue, 7 Mar 2023 07:54:49 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9293D3858D39 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1678175689; bh=Dmc6Pr0U5SgxTuCVnpJvi1y6Zoa2qedp/8mmcqh7Sl8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=cEWraWhPzzjTlUaQNlXu0XWtsXtPD7XdDXMMdgJEbyxFnsDM8zLegN5rZeEJm9GV6 s3pQff5i2Ukk5wgwEMaBAFgjt+eGNmdJHigNC+WF8pXcR75puU9F8tG/jiaMzdlm5P 6tWelXDdmcJEy9VMS2pxY5GuHFyHhmNfMFroFgbU= From: "rguenth at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug sanitizer/108995] Missed signed integer overflow checks in UBsan? since r8-343-g2bf54d93f159210d Date: Tue, 07 Mar 2023 07:54:48 +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: unknown 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: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- 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=3D108995 --- Comment #2 from Richard Biener --- We already fold this on GENERIC to *c =3D -229690488(OVF); with optimization and *c =3D (int) b * 10921; without. It's almost surely through extract_muldiv, we also diagnose t.c: In function =E2=80=98main=E2=80=99: t.c:6:14: warning: integer overflow in expression =E2=80=9865526 * (int)b= =E2=80=99 of type =E2=80=98int=E2=80=99 results in =E2=80=98-1378142932=E2=80=99 [-Woverflow] 6 | *c =3D 65526 * b / 6; | ~~~~~~^~~ the issue seems to be that the C frontend, with optimization, constant folds the initializer of 'b' and with all-constants we ignore sanitization (but emit a diagnostic). Without optimization we run into extract_muldiv doing /* If these operations "cancel" each other, we have the main optimizations of this pass, which occur when either constant is a multiple of the other, in which case we replace this with either an operation or CODE or TCODE. If we have an unsigned type, we cannot do this since it will change the result if the original computation overflowed. */ if (TYPE_OVERFLOW_UNDEFINED (ctype) && ((code =3D=3D MULT_EXPR && tcode =3D=3D EXACT_DIV_EXPR) || (tcode =3D=3D MULT_EXPR && code !=3D TRUNC_MOD_EXPR && code !=3D CEIL_MOD_EXPR && code !=3D FLOOR_MOD_EXPR && code !=3D ROUND_MOD_EXPR && code !=3D MULT_EXPR))) { which is "fine". We do have a few && !TYPE_OVERFLOW_SANITIZED checks around but here we're missing it (I also believe we shouldn't do it this way, but ...). Without optimizing -Wstrict-overflow would diagnose this as well. The following fixes the "bug" at -O0 but leaves the constant folding in the frontend untouched (it could possibly refrain from replacing ops with TREE_OVERFLOW constants when sanitizing overflow). I'm not sure we want a patch like the following though. diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 9aaea71a2fc..a9af4dbd0a3 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -7102,6 +7102,8 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type, if (wi::multiple_of_p (wi::to_wide (op1), wi::to_wide (c), TYPE_SIGN (type))) { + if (TYPE_OVERFLOW_SANITIZED (ctype)) + return NULL_TREE; if (TYPE_OVERFLOW_UNDEFINED (ctype)) *strict_overflow_p =3D true; return fold_build2 (tcode, ctype, fold_convert (ctype, op0), @@ -7112,6 +7114,8 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type, else if (wi::multiple_of_p (wi::to_wide (c), wi::to_wide (op1), TYPE_SIGN (type))) { + if (TYPE_OVERFLOW_SANITIZED (ctype)) + return NULL_TREE; if (TYPE_OVERFLOW_UNDEFINED (ctype)) *strict_overflow_p =3D true; return fold_build2 (code, ctype, fold_convert (ctype, op0),=