From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 315273857816; Sat, 8 Jan 2022 08:54:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 315273857816 From: "cvs-commit at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/89074] valid pointer equality constexpr comparison rejected Date: Sat, 08 Jan 2022 08:54:30 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 9.0 X-Bugzilla-Keywords: rejects-valid X-Bugzilla-Severity: normal X-Bugzilla-Who: cvs-commit at gcc dot gnu.org X-Bugzilla-Status: ASSIGNED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: jakub 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 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: Sat, 08 Jan 2022 08:54:31 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D89074 --- Comment #15 from CVS Commits --- The master branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:51d464b608b38b9e2007948d10b1e0f1dcec142c commit r12-6382-g51d464b608b38b9e2007948d10b1e0f1dcec142c Author: Jakub Jelinek Date: Sat Jan 8 09:53:00 2022 +0100 c++, match.pd: Evaluate in constant evaluation comparisons like &var1 += 12 =3D=3D &var2 + 24 [PR89074] The match.pd address_comparison simplification can only handle ADDR_EXPR comparisons possibly converted to some other type (I wonder if we shouldn't restrict it in address_compare to casts to pointer types or pointer-sized integer types, I think we shouldn't optimize (short) (&var) =3D=3D (short) (&var2) because we really don't know whet= her it will be true or false). On GIMPLE, most of pointer to pointer casts are useless and optimized away and further we have in gimple_fold_stmt_to_constant_1 an optimization that folds &something p+ const_int into &MEM_REF[..., off] On GENERIC, we don't do that and e.g. for constant evaluation it could be pretty harmful if e.g. such pointers are dereferenced, because it can lose what exact field it was starting with etc., all it knows is the base and offset, type and alias set. Instead of teaching the match.pd address_compare about 3 extra variants where one or both compared operands are pointer_plus, this patch attemp= ts to fold operands of comparisons similarly to gimple_fold_stmt_to_consta= nt_1 before calling fold_binary on it. There is another thing though, while we do have (x p+ y) p+ z to x p+ (y + z) simplification which works on GIMPLE well because of the useless pointer conversions, on GENERIC we can have pointer casts in between and at that point we can end up with large expressions like ((type3) (((type2) ((type1) (&var + 2) + 2) + 2) + 2)) etc. Pointer-plus doesn't really care what exact pointer type it has as long as it is a pointer, so the following match.pd simplification for GENERIC only (it is useless for GIMPLE) also moves the cast so that nes= ted p+ can be simplified. Note, I've noticed we don't really diagnose going out of bounds with pointer_plus (unlike e.g. with ARRAY_REF) during constant evaluation, I think another patch for cxx_eval_binary_expression with POINTER_PLUS wi= ll be needed. But it isn't clear to me what exactly it should do in case of subobjects. If we start with address of a whole var, (&var), I guess we should diagnose if the pointer_plus gets before start of the var (i.e. "negative") or 1 byte past the end of the var, but what if we start with &var.field or &var.field[3] ? For &var.field, shall we diagnose out of bounds of field (except perhaps flexible members?) or the whole var? For ARRAY_REFs, I assume we must at least strip all the outer ARRAY_REFs and so start with &var.field too, right? 2022-01-08 Jakub Jelinek PR c++/89074 gcc/ * match.pd ((ptr) (x p+ y) p+ z -> (ptr) (x p+ (y + z))): New GENERIC simplification. gcc/cp/ * constexpr.c (cxx_maybe_fold_addr_pointer_plus): New function. (cxx_eval_binary_expression): Use it. gcc/testsuite/ * g++.dg/cpp1y/constexpr-89074-2.C: New test. * g++.dg/cpp1z/constexpr-89074-1.C: New test.=