From: Marek Polacek Date: Tue, 5 Dec 2023 20:23:52 +0000 (-0500) Subject: c++: fix ICE with sizeof in a template [PR112869] X-Git-Tag: basepoints/gcc-15~3578 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8cccdc2176740f3e034ee6caa49552cf2f142744;p=thirdparty%2Fgcc.git c++: fix ICE with sizeof in a template [PR112869] This test shows that we cannot clear *walk_subtrees in cp_fold_immediate_r when we're in_immediate_context, because that checks even e.g. sk_template_parms, and, as the comment says, affects cp_fold_r as well. Here we had an expression with min ((long int) VIEW_CONVERT_EXPR(bytecount), (long int) <<< Unknown tree: sizeof_expr (int) <<< error >>> >>>) as its sub-expression, and we never evaluated that into min ((long int) bytecount, 4) so the SIZEOF_EXPR leaked into the middle end. We need to make sure we are calling cp_fold on the SIZEOF_EXPR. PR c++/112869 gcc/cp/ChangeLog: * cp-gimplify.cc (cp_fold_immediate_r): Check cp_unevaluated_operand and DECL_IMMEDIATE_FUNCTION_P rather than in_immediate_context. gcc/testsuite/ChangeLog: * g++.dg/template/sizeof18.C: New test. --- diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc index c307e1b62db4..64049f4154e2 100644 --- a/gcc/cp/cp-gimplify.cc +++ b/gcc/cp/cp-gimplify.cc @@ -1179,7 +1179,13 @@ cp_fold_immediate_r (tree *stmt_p, int *walk_subtrees, void *data_) /* No need to look into types or unevaluated operands. NB: This affects cp_fold_r as well. */ - if (TYPE_P (stmt) || unevaluated_p (code) || in_immediate_context ()) + if (TYPE_P (stmt) + || unevaluated_p (code) + /* We do not use in_immediate_context here because it checks + more than is desirable, e.g., sk_template_parms. */ + || cp_unevaluated_operand + || (current_function_decl + && DECL_IMMEDIATE_FUNCTION_P (current_function_decl))) { *walk_subtrees = 0; return NULL_TREE; diff --git a/gcc/testsuite/g++.dg/template/sizeof18.C b/gcc/testsuite/g++.dg/template/sizeof18.C new file mode 100644 index 000000000000..afba9946258c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof18.C @@ -0,0 +1,8 @@ +// PR c++/112869 +// { dg-do compile } + +void min(long, long); +template void Binaryread(int &, T, unsigned long); +template <> void Binaryread(int &, float, unsigned long bytecount) { + min(bytecount, sizeof(int)); +}