summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2022-06-03 14:58:22 -0400
committerPatrick Palka <ppalka@redhat.com>2022-06-11 07:45:13 -0400
commit47ea22015c90df31eae763c6c9e3e4b1fb801c3a (patch)
tree22038745c508f5187395c2d9ef341cd5fe451d79
parentDaily bump. (diff)
downloadgcc-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.cc38
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype82.C10
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
4template<int N>
5void f() {
6 using ty1 = decltype((5 % N) == 0);
7 using ty2 = decltype((5 / N) == 0);
8}
9
10template void f<0>();