diff options
author | Patrick Palka <ppalka@redhat.com> | 2022-06-03 14:58:22 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2022-06-11 07:45:13 -0400 |
commit | 47ea22015c90df31eae763c6c9e3e4b1fb801c3a (patch) | |
tree | 22038745c508f5187395c2d9ef341cd5fe451d79 | |
parent | Daily bump. (diff) | |
download | gcc-47ea22015c90df31eae763c6c9e3e4b1fb801c3a.tar.gz gcc-47ea22015c90df31eae763c6c9e3e4b1fb801c3a.tar.bz2 gcc-47ea22015c90df31eae763c6c9e3e4b1fb801c3a.tar.xz |
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)
-rw-r--r-- | gcc/cp/typeck.cc | 38 | ||||
-rw-r--r-- | 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, | |||
4929 | convert it to this type. */ | 4929 | convert it to this type. */ |
4930 | tree final_type = 0; | 4930 | tree final_type = 0; |
4931 | 4931 | ||
4932 | tree result, result_ovl; | 4932 | tree result; |
4933 | 4933 | ||
4934 | /* Nonzero if this is an operation like MIN or MAX which can | 4934 | /* Nonzero if this is an operation like MIN or MAX which can |
4935 | safely be computed in short if both args are promoted shorts. | 4935 | safely be computed in short if both args are promoted shorts. |
@@ -6253,25 +6253,29 @@ cp_build_binary_op (const op_location_t &location, | |||
6253 | result = build2 (COMPOUND_EXPR, TREE_TYPE (result), | 6253 | result = build2 (COMPOUND_EXPR, TREE_TYPE (result), |
6254 | instrument_expr, result); | 6254 | instrument_expr, result); |
6255 | 6255 | ||
6256 | if (!processing_template_decl) | 6256 | if (resultcode == SPACESHIP_EXPR && !processing_template_decl) |
6257 | result = get_target_expr_sfinae (result, complain); | ||
6258 | |||
6259 | if (!c_inhibit_evaluation_warnings) | ||
6257 | { | 6260 | { |
6258 | if (resultcode == SPACESHIP_EXPR) | 6261 | if (!processing_template_decl) |
6259 | result = get_target_expr_sfinae (result, complain); | 6262 | { |
6260 | op0 = cp_fully_fold (op0); | 6263 | op0 = cp_fully_fold (op0); |
6261 | /* Only consider the second argument if the first isn't overflowed. */ | 6264 | /* Only consider the second argument if the first isn't overflowed. */ |
6262 | if (!CONSTANT_CLASS_P (op0) || TREE_OVERFLOW_P (op0)) | 6265 | if (!CONSTANT_CLASS_P (op0) || TREE_OVERFLOW_P (op0)) |
6263 | return result; | 6266 | return result; |
6264 | op1 = cp_fully_fold (op1); | 6267 | op1 = cp_fully_fold (op1); |
6265 | if (!CONSTANT_CLASS_P (op1) || TREE_OVERFLOW_P (op1)) | 6268 | if (!CONSTANT_CLASS_P (op1) || TREE_OVERFLOW_P (op1)) |
6269 | return result; | ||
6270 | } | ||
6271 | else if (!CONSTANT_CLASS_P (op0) || !CONSTANT_CLASS_P (op1) | ||
6272 | || TREE_OVERFLOW_P (op0) || TREE_OVERFLOW_P (op1)) | ||
6266 | return result; | 6273 | return result; |
6267 | } | ||
6268 | else if (!CONSTANT_CLASS_P (op0) || !CONSTANT_CLASS_P (op1) | ||
6269 | || TREE_OVERFLOW_P (op0) || TREE_OVERFLOW_P (op1)) | ||
6270 | return result; | ||
6271 | 6274 | ||
6272 | result_ovl = fold_build2 (resultcode, build_type, op0, op1); | 6275 | tree result_ovl = fold_build2 (resultcode, build_type, op0, op1); |
6273 | if (TREE_OVERFLOW_P (result_ovl)) | 6276 | if (TREE_OVERFLOW_P (result_ovl)) |
6274 | overflow_warning (location, result_ovl); | 6277 | overflow_warning (location, result_ovl); |
6278 | } | ||
6275 | 6279 | ||
6276 | return result; | 6280 | return result; |
6277 | } | 6281 | } |
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 @@ | |||
1 | // PR c++/105756 | ||
2 | // { dg-do compile { target c++11 } } | ||
3 | |||
4 | template<int N> | ||
5 | void f() { | ||
6 | using ty1 = decltype((5 % N) == 0); | ||
7 | using ty2 = decltype((5 / N) == 0); | ||
8 | } | ||
9 | |||
10 | template void f<0>(); | ||