diff options
author | Patrick Palka <ppalka@redhat.com> | 2022-06-03 14:58:22 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2022-06-03 14:58:22 -0400 |
commit | 0ecb6b906f215ec56df1a555139abe9ad95414fb (patch) | |
tree | fd733587efa6ed05bdb98f9127ba76a216883535 /gcc/cp | |
parent | 284ae8b46f5eef74c0b660a87a7169497f559e73 (diff) | |
download | gcc-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.cc | 38 |
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; } |