From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id AD273382F0BA; Wed, 25 May 2022 15:01:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AD273382F0BA From: "cvs-commit at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/100252] [9/10/11/12/13 Regression] Internal compiler error during template instantiation Date: Wed, 25 May 2022 15:01:40 +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: 10.3.1 X-Bugzilla-Keywords: ice-on-valid-code 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: mpolacek at gcc dot gnu.org X-Bugzilla-Target-Milestone: 9.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 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: Wed, 25 May 2022 15:01:40 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D100252 --- Comment #11 from CVS Commits --- The trunk branch has been updated by Marek Polacek : https://gcc.gnu.org/g:1b661f3f5e712c951e774b3b91fffe4dac734cc7 commit r13-765-g1b661f3f5e712c951e774b3b91fffe4dac734cc7 Author: Marek Polacek Date: Tue Apr 26 15:52:00 2022 -0400 c++: ICE with temporary of class type in DMI [PR100252] Consider struct A { int x; int y =3D x; }; struct B { int x =3D 0; int y =3D A{x}.y; // #1 }; where for #1 we end up with {.x=3D(&)->x, .y=3D(&)->x} that is, two PLACEHOLDER_EXPRs for different types on the same level in a {}. This crashes because our CONSTRUCTOR_PLACEHOLDER_BOUNDARY mechan= ism to avoid replacing unrelated PLACEHOLDER_EXPRs cannot deal with it. Here's why we wound up with those PLACEHOLDER_EXPRs: When we're perform= ing cp_parser_late_parsing_nsdmi for "int y =3D A{x}.y;" we use finish_compound_literal on type=3DA, compound_literal=3D{((struct B *) this)->x}. When digesti= ng this initializer, we call get_nsdmi which creates a PLACEHOLDER_EXPR for A -= - we don't have any object to refer to yet. After digesting, we have {.x=3D((struct B *) this)->x, .y=3D(&)->x} and since we've created a PLACEHOLDER_EXPR inside it, we marked the who= le ctor CONSTRUCTOR_PLACEHOLDER_BOUNDARY. f_c_l creates a TARGET_EXPR and retu= rns TARGET_EXPR x, .y=3D(&)->x}> Then we get to B b =3D {}; and call store_init_value, which digests the {}, which produces {.x=3DNON_LVALUE_EXPR <0>, .y=3D(TARGET_EXPR )->x, .y=3D(&)->x}>).y} lookup_placeholder in constexpr won't find an object to replace the PLACEHOLDER_EXPR for B, because ctx->object will be D.2395 of type A, a= nd we cannot search outward from D.2395 to find 'b'. The call to replace_placeholders in store_init_value will not do anythi= ng: we've marked the inner { } CONSTRUCTOR_PLACEHOLDER_BOUNDARY, and it's o= nly a sub-expression, so replace_placeholders does nothing, so the stays even though now is the perfect time to replace it because we have= an object for it: 'b'. Later, in cp_gimplify_init_expr the *expr_p is D.2395 =3D {.x=3D(&)->x, .y=3D(&)->x} where D.2395 is of type A, but we crash because we hit , which has a different type. My idea was to replace with D.2384 after creating the TARGET_EXPR because that means we have an object we can refer to. Then clear CONSTRUCTOR_PLACEHOLDER_BOUNDARY because we no longer have a PLACEHOLDER_EXPR in the {}. Then store_init_value will be able to replace with 'b', and we should be good to go. We must be careful not to break guaranteed copy elision, so this replacement happens in digest_nsdmi_init where we can see the whole initializer, and avoid replacing any placeholders in TARGET_EXPRs used in the context of initialization/copy elision. This is achieved via the new function called potential_prvalue_result_of. While fixing this problem, I found PR105550, thus the FIXMEs in the tests. PR c++/100252 gcc/cp/ChangeLog: * typeck2.cc (potential_prvalue_result_of): New. (replace_placeholders_for_class_temp_r): New. (digest_nsdmi_init): Call it. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/nsdmi-aggr14.C: New test. * g++.dg/cpp1y/nsdmi-aggr15.C: New test. * g++.dg/cpp1y/nsdmi-aggr16.C: New test. * g++.dg/cpp1y/nsdmi-aggr17.C: New test. * g++.dg/cpp1y/nsdmi-aggr18.C: New test. * g++.dg/cpp1y/nsdmi-aggr19.C: New test.=