On Thu, 2 Jun 2022, Patrick Palka wrote: > On Thu, 2 Jun 2022, Jason Merrill wrote: > > > On 6/1/22 14:20, Patrick Palka wrote: > > > r12-7564-gec0f53a3a542e7 made us instantiate non-constant non-dependent > > > decltype operands by relaxing instantiate_non_dependent_expr to check > > > instantiation_dependent_uneval_expression_p. But as the testcase below > > > demonstrates, this predicate is too permissive here because it allows > > > value-dependent-only expressions to go through and get instantiated > > > ahead of time, which causes us to crash during constexpr evaluation of > > > (5 % N). > > > > Why are we doing constexpr evaluation in unevaluated context? > > Looks like because cp_build_binary_op attempts to fold the resulting > operator expression via cp_fully_fold (which performs speculate > constexpr evaluation): > > 6261 if (!processing_template_decl) > 6262 { > 6263 if (resultcode == SPACESHIP_EXPR) > 6264 result = get_target_expr (result, complain); > 6265 op0 = cp_fully_fold (op0); > 6266 /* Only consider the second argument if the first isn't overflowed. > */ > 6267 if (!CONSTANT_CLASS_P (op0) || TREE_OVERFLOW_P (op0)) > 6268 return result; > 6269 op1 = cp_fully_fold (op1); > 6270 if (!CONSTANT_CLASS_P (op1) || TREE_OVERFLOW_P (op1)) > 6271 return result; > 6272 } > > But in an unevaluated context I suppose we don't need or want to do this > folding. I'll work on a patch to that effect.
Here it is: -- >8 -- Subject: [PATCH] c++: value-dep but not type-dep decltype operand [PR105756] Here we're crashing when instantiating ahead of time the value-dependent but not type-dependent decltype operand (5 % N) == 0, ultimately because cp_build_binary_op folds its operands for sake of its overflow diagnostics, and as part of this folding it performs speculative constexpr evaluation for the operand (5 % N) during which we crash since it's value-dependent. 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 fixes this crash by suppressing cp_build_binary_op's operand folding accordingly. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk/12? The diff was generated with -w to suppress noisy whitespace changes. 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. --- gcc/cp/typeck.cc | 8 ++++++-- gcc/testsuite/g++.dg/cpp0x/decltype82.C | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/decltype82.C diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 190d710cd27..7c910d57b7e 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -6263,10 +6263,13 @@ cp_build_binary_op (const op_location_t &location, result = build2 (COMPOUND_EXPR, TREE_TYPE (result), instrument_expr, result); + if (resultcode == SPACESHIP_EXPR && !processing_template_decl) + result = get_target_expr_sfinae (result, complain); + + if (!c_inhibit_evaluation_warnings) + { if (!processing_template_decl) { - 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)) @@ -6282,6 +6285,7 @@ cp_build_binary_op (const op_location_t &location, 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<int N> +void f() { + using ty1 = decltype((5 % N) == 0); + using ty2 = decltype((5 / N) == 0); +} + +template void f<0>(); -- 2.36.1.210.g2668e3608e