From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1888) id 4F1193939E14; Sat, 11 Jun 2022 12:27:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4F1193939E14 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Patrick Palka To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-8472] c++: value-dep but not type-dep decltype expr [PR105756] X-Act-Checkin: gcc X-Git-Author: Patrick Palka X-Git-Refname: refs/heads/releases/gcc-12 X-Git-Oldrev: 8ca04b41bb1a7d0850e562d37206dfadbc1d64c6 X-Git-Newrev: 47ea22015c90df31eae763c6c9e3e4b1fb801c3a Message-Id: <20220611122723.4F1193939E14@sourceware.org> Date: Sat, 11 Jun 2022 12:27:23 +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: Sat, 11 Jun 2022 12:27:23 -0000 https://gcc.gnu.org/g:47ea22015c90df31eae763c6c9e3e4b1fb801c3a commit r12-8472-g47ea22015c90df31eae763c6c9e3e4b1fb801c3a Author: Patrick Palka Date: Fri Jun 3 14:58:22 2022 -0400 c++: value-dep but not type-dep decltype expr [PR105756] Here during ahead of time instantiation of the value-dependent but not type-dependent decltype expression (5 % N) == 0, cp_build_binary_op folds the operands of the == via cp_fully_fold, which performs speculative constexpr evaluation, and from which we crash for (5 % N) due to the value-dependence. Since the operand folding performed by cp_build_binary_op appears to be solely for sake of diagnosing overflow, and since these diagnostics are suppressed when in an unevaluated context, this patch avoids this crash by suppressing cp_build_binary_op's operand folding accordingly. PR c++/105756 gcc/cp/ChangeLog: * typeck.cc (cp_build_binary_op): Don't fold operands when c_inhibit_evaluation_warnings. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/decltype82.C: New test. (cherry picked from commit 0ecb6b906f215ec56df1a555139abe9ad95414fb) Diff: --- gcc/cp/typeck.cc | 38 ++++++++++++++++++--------------- gcc/testsuite/g++.dg/cpp0x/decltype82.C | 10 +++++++++ 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 0da6f2485d0..a6c393647b2 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -4929,7 +4929,7 @@ cp_build_binary_op (const op_location_t &location, convert it to this type. */ tree final_type = 0; - tree result, result_ovl; + tree result; /* Nonzero if this is an operation like MIN or MAX which can safely be computed in short if both args are promoted shorts. @@ -6253,25 +6253,29 @@ cp_build_binary_op (const op_location_t &location, result = build2 (COMPOUND_EXPR, TREE_TYPE (result), instrument_expr, result); - if (!processing_template_decl) + if (resultcode == SPACESHIP_EXPR && !processing_template_decl) + result = get_target_expr_sfinae (result, complain); + + if (!c_inhibit_evaluation_warnings) { - if (resultcode == SPACESHIP_EXPR) - result = get_target_expr_sfinae (result, complain); - op0 = cp_fully_fold (op0); - /* Only consider the second argument if the first isn't overflowed. */ - if (!CONSTANT_CLASS_P (op0) || TREE_OVERFLOW_P (op0)) - return result; - op1 = cp_fully_fold (op1); - if (!CONSTANT_CLASS_P (op1) || TREE_OVERFLOW_P (op1)) + if (!processing_template_decl) + { + op0 = cp_fully_fold (op0); + /* Only consider the second argument if the first isn't overflowed. */ + if (!CONSTANT_CLASS_P (op0) || TREE_OVERFLOW_P (op0)) + return result; + op1 = cp_fully_fold (op1); + if (!CONSTANT_CLASS_P (op1) || TREE_OVERFLOW_P (op1)) + return result; + } + else if (!CONSTANT_CLASS_P (op0) || !CONSTANT_CLASS_P (op1) + || TREE_OVERFLOW_P (op0) || TREE_OVERFLOW_P (op1)) return result; - } - else if (!CONSTANT_CLASS_P (op0) || !CONSTANT_CLASS_P (op1) - || TREE_OVERFLOW_P (op0) || TREE_OVERFLOW_P (op1)) - return result; - result_ovl = fold_build2 (resultcode, build_type, op0, op1); - if (TREE_OVERFLOW_P (result_ovl)) - overflow_warning (location, result_ovl); + tree result_ovl = fold_build2 (resultcode, build_type, op0, op1); + if (TREE_OVERFLOW_P (result_ovl)) + overflow_warning (location, result_ovl); + } return result; } diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype82.C b/gcc/testsuite/g++.dg/cpp0x/decltype82.C new file mode 100644 index 00000000000..915e5e37675 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype82.C @@ -0,0 +1,10 @@ +// PR c++/105756 +// { dg-do compile { target c++11 } } + +template +void f() { + using ty1 = decltype((5 % N) == 0); + using ty2 = decltype((5 / N) == 0); +} + +template void f<0>();