diff options
author | Jakub Jelinek <jakub@redhat.com> | 2025-03-12 08:27:17 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2025-03-12 08:27:17 +0100 |
commit | da967f0ff324053304b350fdb18384607a346ebd (patch) | |
tree | 6c764a8c41575140af32a06341df98afa1ee2cc2 | |
parent | 28b05e4317a6eade2ba46076ef17f9e138c57a34 (diff) | |
download | gcc-da967f0ff324053304b350fdb18384607a346ebd.zip gcc-da967f0ff324053304b350fdb18384607a346ebd.tar.gz gcc-da967f0ff324053304b350fdb18384607a346ebd.tar.bz2 |
builtins: Fix up strspn/strcspn folding [PR119219]
The PR119204 r15-7955 fix caused some regressions.
The problem is that the fold_builtin* APIs document that expr is
either a CALL_EXPR of the call or NULL, so using TREE_TYPE (expr)
can crash e.g. during constexpr evaluation etc.
As can be seen in the surrounding patch, for the neighbouring builtins
(both modf and strpbrk) fold_builtin_2 passes down type, which is the
result type, TREE_TYPE (TREE_TYPE (fndecl)) and those builtins use it
to build the return value, while strspn was always building size_type_node
and strcspn had this change from that to TREE_TYPE (expr).
The patch passes type to these two and uses it there as well.
The patch keeps passing expr because it is used in the
check_nul_terminated_array calls done for both strspn and strcspn,
those calls clearly can deal with NULL expr but prefer if it is non-NULL
for some warning.
2025-03-12 Jakub Jelinek <jakub@redhat.com>
PR middle-end/119204
PR middle-end/119219
* builtins.cc (fold_builtin_2): Pass type as another argument
to fold_builtin_strspn and fold_builtin_strcspn.
(fold_builtin_strspn): Add type argument, use it instead of
size_type_node.
(fold_builtin_strcspn): Add type argument, use it instead of
TREE_TYPE (expr).
-rw-r--r-- | gcc/builtins.cc | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/gcc/builtins.cc b/gcc/builtins.cc index 02556e6..956d3cc 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -176,8 +176,8 @@ static tree fold_builtin_iseqsig (location_t, tree, tree); static tree fold_builtin_varargs (location_t, tree, tree*, int); static tree fold_builtin_strpbrk (location_t, tree, tree, tree, tree); -static tree fold_builtin_strspn (location_t, tree, tree, tree); -static tree fold_builtin_strcspn (location_t, tree, tree, tree); +static tree fold_builtin_strspn (location_t, tree, tree, tree, tree); +static tree fold_builtin_strcspn (location_t, tree, tree, tree, tree); static rtx expand_builtin_object_size (tree); static rtx expand_builtin_memory_chk (tree, rtx, machine_mode, @@ -10800,10 +10800,10 @@ fold_builtin_2 (location_t loc, tree expr, tree fndecl, tree arg0, tree arg1) return fold_builtin_modf (loc, arg0, arg1, type); case BUILT_IN_STRSPN: - return fold_builtin_strspn (loc, expr, arg0, arg1); + return fold_builtin_strspn (loc, expr, arg0, arg1, type); case BUILT_IN_STRCSPN: - return fold_builtin_strcspn (loc, expr, arg0, arg1); + return fold_builtin_strcspn (loc, expr, arg0, arg1, type); case BUILT_IN_STRPBRK: return fold_builtin_strpbrk (loc, expr, arg0, arg1, type); @@ -11304,7 +11304,7 @@ fold_builtin_strpbrk (location_t loc, tree, tree s1, tree s2, tree type) form of the builtin function call. */ static tree -fold_builtin_strspn (location_t loc, tree expr, tree s1, tree s2) +fold_builtin_strspn (location_t loc, tree expr, tree s1, tree s2, tree type) { if (!validate_arg (s1, POINTER_TYPE) || !validate_arg (s2, POINTER_TYPE)) @@ -11320,8 +11320,7 @@ fold_builtin_strspn (location_t loc, tree expr, tree s1, tree s2) if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')) /* Evaluate and ignore both arguments in case either one has side-effects. */ - return omit_two_operands_loc (loc, size_type_node, size_zero_node, - s1, s2); + return omit_two_operands_loc (loc, type, size_zero_node, s1, s2); return NULL_TREE; } @@ -11344,7 +11343,7 @@ fold_builtin_strspn (location_t loc, tree expr, tree s1, tree s2) form of the builtin function call. */ static tree -fold_builtin_strcspn (location_t loc, tree expr, tree s1, tree s2) +fold_builtin_strcspn (location_t loc, tree expr, tree s1, tree s2, tree type) { if (!validate_arg (s1, POINTER_TYPE) || !validate_arg (s2, POINTER_TYPE)) @@ -11360,8 +11359,7 @@ fold_builtin_strcspn (location_t loc, tree expr, tree s1, tree s2) { /* Evaluate and ignore argument s2 in case it has side-effects. */ - return omit_one_operand_loc (loc, TREE_TYPE (expr), - size_zero_node, s2); + return omit_one_operand_loc (loc, type, size_zero_node, s2); } /* If the second argument is "", return __builtin_strlen(s1). */ @@ -11375,7 +11373,7 @@ fold_builtin_strcspn (location_t loc, tree expr, tree s1, tree s2) if (!fn) return NULL_TREE; - return fold_convert_loc (loc, TREE_TYPE (expr), + return fold_convert_loc (loc, type, build_call_expr_loc (loc, fn, 1, s1)); } return NULL_TREE; |