]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: fix ICE with sizeof in a template [PR112869]
authorMarek Polacek <polacek@redhat.com>
Tue, 5 Dec 2023 20:23:52 +0000 (15:23 -0500)
committerMarek Polacek <polacek@redhat.com>
Thu, 14 Dec 2023 21:05:37 +0000 (16:05 -0500)
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<long unsigned int>(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.

gcc/cp/cp-gimplify.cc
gcc/testsuite/g++.dg/template/sizeof18.C [new file with mode: 0644]

index c307e1b62db4d9350ba41432a69e36bc25c3359e..64049f4154e2240a913c0b71193c2fd8dbb8bf82 100644 (file)
@@ -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 (file)
index 0000000..afba994
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/112869
+// { dg-do compile }
+
+void min(long, long);
+template <class T> void Binaryread(int &, T, unsigned long);
+template <> void Binaryread(int &, float, unsigned long bytecount) {
+  min(bytecount, sizeof(int));
+}