aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2025-01-16 12:53:21 -0800
committerAndrew Pinski <quic_apinski@quicinc.com>2025-01-21 14:07:47 -0800
commit0d25d45c9d3a54b21f9dce43beb0b5ced4db0409 (patch)
tree11c79a1a7087f262f382cf659a6b0f3b7998c7c5 /gcc
parent16d778239397b2f70a1e0680c0b82ae6ee98fe9e (diff)
downloadgcc-0d25d45c9d3a54b21f9dce43beb0b5ced4db0409.zip
gcc-0d25d45c9d3a54b21f9dce43beb0b5ced4db0409.tar.gz
gcc-0d25d45c9d3a54b21f9dce43beb0b5ced4db0409.tar.bz2
c++: Don't call fold from cp_fold if one of the operands is an error_mark [PR118525]
While adding a new match pattern, g++.dg/cpp2a/consteval36.C started to ICE and that was because we would call fold even if one of the operands of the comparison was an error_mark_node. I found a new testcase which also ICEs before this patch too so show the issue was latent. So there is code in cp_fold to avoid calling fold when one of the operands become error_mark_node but with the addition of consteval, the replacement of an invalid call is replaced before the call to cp_fold and there is no way to pop up the error_mark. So this patch changes the current code to check if the operands of the expression are error_mark_node before checking if the folded operand is different from the previous one. Bootstrapped and tested on x86_64-linux-gnu. PR c++/118525 gcc/cp/ChangeLog: * cp-gimplify.cc (cp_fold): Check operands of unary, binary, cond/vec_cond and array_ref for error_mark before checking if the operands had changed. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/consteval38.C: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/cp-gimplify.cc99
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/consteval38.C11
2 files changed, 53 insertions, 57 deletions
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index c7074b0..4ec3de1 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -3005,19 +3005,16 @@ cp_fold (tree x, fold_flags_t flags)
loc = EXPR_LOCATION (x);
op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
- if (code == CONVERT_EXPR
+ if (op0 == error_mark_node)
+ x = error_mark_node;
+ else if (code == CONVERT_EXPR
&& SCALAR_TYPE_P (TREE_TYPE (x))
&& op0 != void_node)
/* During parsing we used convert_to_*_nofold; re-convert now using the
folding variants, since fold() doesn't do those transformations. */
x = fold (convert (TREE_TYPE (x), op0));
else if (op0 != TREE_OPERAND (x, 0))
- {
- if (op0 == error_mark_node)
- x = error_mark_node;
- else
- x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
- }
+ x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
else
x = fold (x);
@@ -3087,20 +3084,17 @@ cp_fold (tree x, fold_flags_t flags)
op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
finish_unary:
- if (op0 != TREE_OPERAND (x, 0))
+ if (op0 == error_mark_node)
+ x = error_mark_node;
+ else if (op0 != TREE_OPERAND (x, 0))
{
- if (op0 == error_mark_node)
- x = error_mark_node;
- else
+ x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
+ if (code == INDIRECT_REF
+ && (INDIRECT_REF_P (x) || TREE_CODE (x) == MEM_REF))
{
- x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
- if (code == INDIRECT_REF
- && (INDIRECT_REF_P (x) || TREE_CODE (x) == MEM_REF))
- {
- TREE_READONLY (x) = TREE_READONLY (org_x);
- TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
- TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
- }
+ TREE_READONLY (x) = TREE_READONLY (org_x);
+ TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
+ TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
}
}
else
@@ -3190,13 +3184,10 @@ cp_fold (tree x, fold_flags_t flags)
op0, op1);
}
- if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
- {
- if (op0 == error_mark_node || op1 == error_mark_node)
- x = error_mark_node;
- else
- x = fold_build2_loc (loc, code, TREE_TYPE (x), op0, op1);
- }
+ if (op0 == error_mark_node || op1 == error_mark_node)
+ x = error_mark_node;
+ else if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
+ x = fold_build2_loc (loc, code, TREE_TYPE (x), op0, op1);
else
x = fold (x);
@@ -3268,17 +3259,14 @@ cp_fold (tree x, fold_flags_t flags)
}
}
- if (op0 != TREE_OPERAND (x, 0)
- || op1 != TREE_OPERAND (x, 1)
- || op2 != TREE_OPERAND (x, 2))
- {
- if (op0 == error_mark_node
- || op1 == error_mark_node
- || op2 == error_mark_node)
- x = error_mark_node;
- else
- x = fold_build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
- }
+ if (op0 == error_mark_node
+ || op1 == error_mark_node
+ || op2 == error_mark_node)
+ x = error_mark_node;
+ else if (op0 != TREE_OPERAND (x, 0)
+ || op1 != TREE_OPERAND (x, 1)
+ || op2 != TREE_OPERAND (x, 2))
+ x = fold_build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
else
x = fold (x);
@@ -3462,14 +3450,14 @@ cp_fold (tree x, fold_flags_t flags)
FOR_EACH_VEC_SAFE_ELT (elts, i, p)
{
tree op = cp_fold (p->value, flags);
- if (op != p->value)
+ if (op == error_mark_node)
+ {
+ x = error_mark_node;
+ vec_free (nelts);
+ break;
+ }
+ else if (op != p->value)
{
- if (op == error_mark_node)
- {
- x = error_mark_node;
- vec_free (nelts);
- break;
- }
if (nelts == NULL)
nelts = elts->copy ();
(*nelts)[i].value = op;
@@ -3516,23 +3504,20 @@ cp_fold (tree x, fold_flags_t flags)
op2 = cp_fold (TREE_OPERAND (x, 2), flags);
op3 = cp_fold (TREE_OPERAND (x, 3), flags);
- if (op0 != TREE_OPERAND (x, 0)
+ if (op0 == error_mark_node
+ || op1 == error_mark_node
+ || op2 == error_mark_node
+ || op3 == error_mark_node)
+ x = error_mark_node;
+ else if (op0 != TREE_OPERAND (x, 0)
|| op1 != TREE_OPERAND (x, 1)
|| op2 != TREE_OPERAND (x, 2)
|| op3 != TREE_OPERAND (x, 3))
{
- if (op0 == error_mark_node
- || op1 == error_mark_node
- || op2 == error_mark_node
- || op3 == error_mark_node)
- x = error_mark_node;
- else
- {
- x = build4_loc (loc, code, TREE_TYPE (x), op0, op1, op2, op3);
- TREE_READONLY (x) = TREE_READONLY (org_x);
- TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
- TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
- }
+ x = build4_loc (loc, code, TREE_TYPE (x), op0, op1, op2, op3);
+ TREE_READONLY (x) = TREE_READONLY (org_x);
+ TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
+ TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
}
x = fold (x);
diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval38.C b/gcc/testsuite/g++.dg/cpp2a/consteval38.C
new file mode 100644
index 0000000..cc9f7ba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/consteval38.C
@@ -0,0 +1,11 @@
+// PR c++/118525
+// { dg-do compile { target c++20 } }
+
+// Make sure we don't ICE
+consteval int id (int i) { return i; }
+
+void
+g (int i)
+{
+ 1 ? 1 : id (i) ^ 1; // { dg-error "call to consteval function|'i' is not a constant expression" }
+}