]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
builtins: Only fold abs/absu if it is sane [PR123703]
authorJakub Jelinek <jakub@redhat.com>
Fri, 23 Jan 2026 09:37:46 +0000 (10:37 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 23 Jan 2026 09:37:46 +0000 (10:37 +0100)
To my surprise the C FE marks as builtin even a declaration which has incorrect
return type.  Normally gimple_builtin_call_types_compatible_p etc. will
just punt in cases where the return type is wrong, but builtins.cc doesn't
use that.  For e.g. the mathfn builtins like sqrt and many others, it will
punt on weird return types, but for fold_builtin_abs it doesn't and happily
tests TYPE_UNSIGNED on it and fold_convert the integral operand to it etc.,
which ICEs if the return type is aggregate.

The following patch fixes it by punting if type is not integral.

2026-01-23  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/123703
* builtins.cc (fold_builtin_abs): Return NULL_TREE if type is not
integral.

* gcc.c-torture/compile/pr123703.c: New test.

gcc/builtins.cc
gcc/testsuite/gcc.c-torture/compile/pr123703.c [new file with mode: 0644]

index a16a25c8be9d604ae19bdf5ef1f08602d9e339d6..28454c5377700ca28c9124b8d0dc9e02dd6ca8f0 100644 (file)
@@ -9538,7 +9538,7 @@ fold_builtin_fabs (location_t loc, tree arg, tree type)
 static tree
 fold_builtin_abs (location_t loc, tree arg, tree type)
 {
-  if (!validate_arg (arg, INTEGER_TYPE))
+  if (!validate_arg (arg, INTEGER_TYPE) || !INTEGRAL_TYPE_P (type))
     return NULL_TREE;
 
   if (TYPE_UNSIGNED (type))
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr123703.c b/gcc/testsuite/gcc.c-torture/compile/pr123703.c
new file mode 100644 (file)
index 0000000..a7f68a6
--- /dev/null
@@ -0,0 +1,10 @@
+/* PR middle-end/123703 */
+
+struct S { int a; };
+struct S abs (int);
+
+struct S
+bar (int j)
+{
+  return abs (j);
+}