From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 422A83836005; Fri, 14 Jan 2022 11:08:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 422A83836005 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: Fri, 14 Jan 2022 11:08:52 +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: Fri, 14 Jan 2022 11:08:53 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D89074 --- Comment #16 from CVS Commits --- The master branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:d686d5d85c23451c03799dc55e456b73065f7333 commit r12-6578-gd686d5d85c23451c03799dc55e456b73065f7333 Author: Jakub Jelinek Date: Fri Jan 14 12:07:49 2022 +0100 c++: Reject in constant evaluation address comparisons of start of one = var and end of another [PR89074] The following testcase used to be incorrectly accepted. The match.pd optimization that uses address_compare punts on folding comparison of start of one object and end of another one only when those addresses are cast to integral types, when the comparison is done on pointer types it assumes undefined behavior and decides to fold the comparison such that the addresses don't compare equal even when they at runtime they could be equal. But C++ says it is undefined behavior and so during constant evaluation we should reject those, so this patch adds !folding_initializer && check to that spot. Note, address_compare has some special cases, e.g. it assumes that static vars are never adjacent to automatic vars, which is the case for the usual layout where automatic vars are on the stack and after .rodata/.data sections there is heap: /* Assume that automatic variables can't be adjacent to global variables. */ else if (is_global_var (base0) !=3D is_global_var (base1)) ; Is it ok that during constant evaluation we don't treat those as undefi= ned behavior, or shall that be with !folding_initializer && too? Another special case is: if ((DECL_P (base0) && TREE_CODE (base1) =3D=3D STRING_CST) || (TREE_CODE (base0) =3D=3D STRING_CST && DECL_P (base1)) || (TREE_CODE (base0) =3D=3D STRING_CST && TREE_CODE (base1) =3D=3D STRING_CST && ioff0 >=3D 0 && ioff1 >=3D 0 && ioff0 < TREE_STRING_LENGTH (base0) && ioff1 < TREE_STRING_LENGTH (base1) /* This is a too conservative test that the STRING_CSTs will not end up being string-merged. */ && strncmp (TREE_STRING_POINTER (base0) + ioff0, TREE_STRING_POINTER (base1) + ioff1, MIN (TREE_STRING_LENGTH (base0) - ioff0, TREE_STRING_LENGTH (base1) - ioff1)) !=3D 0= )) ; else if (!DECL_P (base0) || !DECL_P (base1)) return 2; Here we similarly assume that vars aren't adjacent to string literals or vice versa. Do we need to stick !folding_initializer && to those DECL_P vs. STRING_CST cases? Though, because of the return 2; for non-DECL_P that would mean rejecting comparisons like &var =3D=3D &"foo= bar"[3] etc. which ought to be fine, no? So perhaps we need to watch for decls. vs. STRING_CSTs like for DECLs whether the address is at the sta= rt or at the end of the string literal or somewhere in between (at least for folding_initializer)? And yet another chapter but probably unsolvable is comparison of string literal addresses. I think pedantically in C++ &"foo"[0] =3D=3D &"foo"[0] is undefined behavior, different occurences = of the same string literals might still not be merged in some implementati= ons. But constexpr const char *s =3D "foo"; &s[0] =3D=3D &s[0] should be wel= l defined, and we aren't tracking anywhere whether the string literal was the same= one or different (and I think other compilers don't track that either). 2022-01-14 Jakub Jelinek PR c++/89074 * fold-const.c (address_compare): Punt on comparison of address= of one object with address of end of another object if folding_initializer. * g++.dg/cpp1y/constexpr-89074-1.C: New test.=