aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2022-06-03 14:58:22 -0400
committerPatrick Palka <ppalka@redhat.com>2022-06-03 14:58:22 -0400
commit0ecb6b906f215ec56df1a555139abe9ad95414fb (patch)
treefd733587efa6ed05bdb98f9127ba76a216883535 /gcc/cp
parent284ae8b46f5eef74c0b660a87a7169497f559e73 (diff)
downloadgcc-0ecb6b906f215ec56df1a555139abe9ad95414fb.zip
gcc-0ecb6b906f215ec56df1a555139abe9ad95414fb.tar.gz
gcc-0ecb6b906f215ec56df1a555139abe9ad95414fb.tar.bz2
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.
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/typeck.cc38
1 files changed, 21 insertions, 17 deletions
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 190d710..f9ce14f 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -4939,7 +4939,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.
@@ -6263,25 +6263,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;
}