From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 8B89538708C6; Thu, 9 May 2024 04:26:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8B89538708C6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1715228800; bh=9gos/2Ld3egLwtqlzRXtjOa9kGa9EkmFDn70YaUP6Uw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ydm9rNGnG+S+9AYP/YYf758rhvVYkyZrE/nWgi1J++vYshO+19jLdHxjKeCVBnamF NlS44HZr5NRHEcMcjl0b0CrBkyTpbqeK4lZyFr+BPN1vC5Puggpu2DCilT7W9ntgzr sBgK25EtPQY+ZX5NzZIupEyEIrD4l6B61E2OQb1w= From: "cvs-commit at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/111284] [11/12/13 Regression] Some passing-by-value parameters are mishandled since GCC 9, affecting libstdc++'s constexpr std::string Date: Thu, 09 May 2024 04:26:39 +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: 13.2.0 X-Bugzilla-Keywords: accepts-invalid, 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: P2 X-Bugzilla-Assigned-To: jakub at gcc dot gnu.org X-Bugzilla-Target-Milestone: 11.5 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=3D111284 --- Comment #12 from GCC Commits --- The releases/gcc-13 branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:6f1b3f9c97e17aa717ae61bc70afa27adcb7ef44 commit r13-8731-g6f1b3f9c97e17aa717ae61bc70afa27adcb7ef44 Author: Jakub Jelinek Date: Thu Apr 25 20:45:04 2024 +0200 c++: Fix constexpr evaluation of parameters passed by invisible referen= ce [PR111284] My r9-6136 changes to make a copy of constexpr function bodies before genericization modifies it broke the constant evaluation of non-POD arguments passed by value. In the callers such arguments are passed as reference to usually a TARGET_EXPR, but on the callee side until genericization they are just direct uses of a PARM_DECL with some class type. In cxx_bind_parameters_in_call I've used convert_from_reference to pretend it is passed by value and then cxx_eval_constant_expression is called there and evaluates that as an rvalue, followed by adjust_temp_type if the types don't match exactly (e.g. const Foo argument and passing to it reference to Foo TARGET_EXPR). The reason this doesn't work is that when the TARGET_EXPR in the caller is constant initialized, this for it is the address of the TARGET_EXPR_SLOT, but if the code later on pretends the PARM_DECL is just initialized to = the rvalue of the constant evaluation of the TARGET_EXPR, it is as if there is a bitwise copy of the TARGET_EXPR to the callee, so this in the call= ee is then address of the PARM_DECL in the callee. The following patch attempts to fix that by constexpr evaluation of such arguments in the caller as an lvalue instead of rvalue, and on the call= ee side when seeing such a PARM_DECL, if we want an lvalue, lookup the val= ue (lvalue) saved in ctx->globals (if any), and if wanting an rvalue, recursing with vc_prvalue on the looked up value (because it is there as an lvalue, nor rvalue). adjust_temp_type doesn't work for lvalues of non-scalarish types, for such types it relies on changing the type of a CONSTRUCTOR, but on the other side we know what we pass to the argument is addressable, so the patch on type mismatch takes address of the argument value, casts to reference to the desired type and dereferences it. 2024-04-25 Jakub Jelinek PR c++/111284 * constexpr.cc (cxx_bind_parameters_in_call): For PARM_DECLs wi= th TREE_ADDRESSABLE types use vc_glvalue rather than vc_prvalue for cxx_eval_constant_expression and if it doesn't have the same type as it should, cast the reference type to reference to type before convert_from_reference and instead of adjust_temp_type take address of the arg, cast to reference to type and then convert_from_reference. (cxx_eval_constant_expression) : For lval case on parameters with TREE_ADDRESSABLE types lookup result in ctx->globals if possible. Otherwise if lookup in ctx->globals was successful for parameter with TREE_ADDRESSABLE type, recurse with vc_prvalue on the returned value. * g++.dg/cpp1z/constexpr-111284.C: New test. (cherry picked from commit f541757ba4632e204169dd08a5f10c782199af42)=