From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1734) id 6BAE93858D3C; Thu, 24 Mar 2022 17:12:49 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6BAE93858D3C MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Marek Polacek To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-7803] c++: FIX_TRUNC_EXPR in tsubst [PR102990] X-Act-Checkin: gcc X-Git-Author: Marek Polacek X-Git-Refname: refs/heads/trunk X-Git-Oldrev: 647537adefb34041cc2d44585252fd765cc0daae X-Git-Newrev: f0530882d99abc410bb080051aa04e5cea848f18 Message-Id: <20220324171249.6BAE93858D3C@sourceware.org> Date: Thu, 24 Mar 2022 17:12:49 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 Mar 2022 17:12:49 -0000 https://gcc.gnu.org/g:f0530882d99abc410bb080051aa04e5cea848f18 commit r12-7803-gf0530882d99abc410bb080051aa04e5cea848f18 Author: Marek Polacek Date: Tue Mar 22 18:42:27 2022 -0400 c++: FIX_TRUNC_EXPR in tsubst [PR102990] This is a crash where a FIX_TRUNC_EXPR gets into tsubst_copy_and_build where it hits gcc_unreachable (). The history of tsubst_copy_and_build/FIX_TRUNC_EXPR is such that it was introduced in r181478, but it did the wrong thing, whereupon it was turned into gcc_unreachable () in r258821 (see this thread: ). In a template, we should never create a FIX_TRUNC_EXPR (that's what conv_unsafe_in_template_p is for). But in this test we are NOT in a template when we call digest_nsdmi_init which ends up calling convert_like, converting 1.0e+0 to int, so convert_to_integer_1 gives us a FIX_TRUNC_EXPR. But then when we get to parsing f's parameters, we are in a template when processing decltype(Helpers{}), and since r268321, when the compound literal isn't instantiation-dependent and the type isn't type-dependent, finish_compound_literal falls back to the normal processing, so it calls digest_init, which does fold_non_dependent_init and since the FIX_TRUNC_EXPR isn't dependent, we instantiate and therefore crash in tsubst_copy_and_build. The fateful call to fold_non_dependent_init comes from massage_init_elt, We shouldn't be calling f_n_d_i on the result of get_nsdmi. This we can avoid by eschewing calling f_n_d_i on CONSTRUCTORs; their elements have already been folded. PR c++/102990 gcc/cp/ChangeLog: * typeck2.cc (massage_init_elt): Avoid folding CONSTRUCTORs. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/nsdmi-template22.C: New test. * g++.dg/cpp0x/nsdmi-template23.C: New test. Diff: --- gcc/cp/typeck2.cc | 13 +++++++++---- gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C | 13 +++++++++++++ gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C | 13 +++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc index a4c825fc34d..cebe6acf487 100644 --- a/gcc/cp/typeck2.cc +++ b/gcc/cp/typeck2.cc @@ -1433,10 +1433,15 @@ massage_init_elt (tree type, tree init, int nested, int flags, new_flags |= LOOKUP_AGGREGATE_PAREN_INIT; init = digest_init_r (type, init, nested ? 2 : 1, new_flags, complain); /* When we defer constant folding within a statement, we may want to - defer this folding as well. */ - tree t = fold_non_dependent_init (init, complain); - if (TREE_CONSTANT (t)) - init = t; + defer this folding as well. Don't call this on CONSTRUCTORs because + their elements have already been folded, and we must avoid folding + the result of get_nsdmi. */ + if (TREE_CODE (init) != CONSTRUCTOR) + { + tree t = fold_non_dependent_init (init, complain); + if (TREE_CONSTANT (t)) + init = t; + } return init; } diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C new file mode 100644 index 00000000000..4ed2501035c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C @@ -0,0 +1,13 @@ +// PR c++/102990 +// { dg-do compile { target c++11 } } + +struct knob_t { + /* Let's create a FIX_TRUNC_EXPR. */ + int value = 1.0; +}; + +struct Helpers { + knob_t inputs; +}; + +template void f(decltype(Helpers{})); diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C new file mode 100644 index 00000000000..240cab4347a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C @@ -0,0 +1,13 @@ +// PR c++/102990 +// { dg-do compile { target c++11 } } + +struct knob_t { + /* Let's create a FLOAT_EXPR. */ + double value = 1UL; +}; + +struct Helpers { + knob_t inputs; +}; + +template void f(decltype(Helpers{}));