Commit 5fcfe0b2 by Kazu Hirata Committed by Kazu Hirata

re PR tree-optimization/19967 (built-in folding causes excess diagnostics)

	PR tree-optimization/19967
	* builtins.c (expand_builtin_strstr, expand_builtin_strpbrk,
	expand_builtin_strchr, expand_builtin_strrchr): Take a new
	argument TYPE.  Adjust calls to fold_builtin_XXX.
	(expand_builtin, fold_builtin_1): Adjust calls to
	expand_builtin_XXX.
	(fold_builtin_strchr, fold_builtin_strpbrk,
	fold_builtin_strstr, fold_builtin_strrchr): Convert the folded
	result to a requested type TYPE.

	* testsuite/gcc.dg/pr19967.c: New.

From-SVN: r95109
parent de332a85
...@@ -5,6 +5,16 @@ ...@@ -5,6 +5,16 @@
find_basic_blocks. find_basic_blocks.
* config/sh/sh.c (sh_output_mi_thunk): Likewise. * config/sh/sh.c (sh_output_mi_thunk): Likewise.
PR tree-optimization/19967
* builtins.c (expand_builtin_strstr, expand_builtin_strpbrk,
expand_builtin_strchr, expand_builtin_strrchr): Take a new
argument TYPE. Adjust calls to fold_builtin_XXX.
(expand_builtin, fold_builtin_1): Adjust calls to
expand_builtin_XXX.
(fold_builtin_strchr, fold_builtin_strpbrk,
fold_builtin_strstr, fold_builtin_strrchr): Convert the folded
result to a requested type TYPE.
2005-02-16 Jakub Jelinek <jakub@redhat.com> 2005-02-16 Jakub Jelinek <jakub@redhat.com>
PR middle-end/19857 PR middle-end/19857
......
...@@ -124,10 +124,10 @@ static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode); ...@@ -124,10 +124,10 @@ static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
static rtx expand_builtin_memset (tree, rtx, enum machine_mode); static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
static rtx expand_builtin_bzero (tree); static rtx expand_builtin_bzero (tree);
static rtx expand_builtin_strlen (tree, rtx, enum machine_mode); static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
static rtx expand_builtin_strstr (tree, rtx, enum machine_mode); static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode); static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
static rtx expand_builtin_strchr (tree, rtx, enum machine_mode); static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode); static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
static rtx expand_builtin_alloca (tree, rtx); static rtx expand_builtin_alloca (tree, rtx);
static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab); static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
static rtx expand_builtin_frame_address (tree, tree); static rtx expand_builtin_frame_address (tree, tree);
...@@ -165,7 +165,7 @@ static tree fold_builtin_bitop (tree); ...@@ -165,7 +165,7 @@ static tree fold_builtin_bitop (tree);
static tree fold_builtin_memcpy (tree); static tree fold_builtin_memcpy (tree);
static tree fold_builtin_mempcpy (tree, tree, int); static tree fold_builtin_mempcpy (tree, tree, int);
static tree fold_builtin_memmove (tree, tree); static tree fold_builtin_memmove (tree, tree);
static tree fold_builtin_strchr (tree); static tree fold_builtin_strchr (tree, tree);
static tree fold_builtin_memcmp (tree); static tree fold_builtin_memcmp (tree);
static tree fold_builtin_strcmp (tree); static tree fold_builtin_strcmp (tree);
static tree fold_builtin_strncmp (tree); static tree fold_builtin_strncmp (tree);
...@@ -179,9 +179,9 @@ static tree fold_builtin_abs (tree, tree); ...@@ -179,9 +179,9 @@ static tree fold_builtin_abs (tree, tree);
static tree fold_builtin_unordered_cmp (tree, enum tree_code, enum tree_code); static tree fold_builtin_unordered_cmp (tree, enum tree_code, enum tree_code);
static tree fold_builtin_1 (tree, bool); static tree fold_builtin_1 (tree, bool);
static tree fold_builtin_strpbrk (tree); static tree fold_builtin_strpbrk (tree, tree);
static tree fold_builtin_strstr (tree); static tree fold_builtin_strstr (tree, tree);
static tree fold_builtin_strrchr (tree); static tree fold_builtin_strrchr (tree, tree);
static tree fold_builtin_strcat (tree); static tree fold_builtin_strcat (tree);
static tree fold_builtin_strncat (tree); static tree fold_builtin_strncat (tree);
static tree fold_builtin_strspn (tree); static tree fold_builtin_strspn (tree);
...@@ -2534,11 +2534,11 @@ expand_builtin_strlen (tree arglist, rtx target, ...@@ -2534,11 +2534,11 @@ expand_builtin_strlen (tree arglist, rtx target,
in TARGET, if convenient (and in mode MODE if that's convenient). */ in TARGET, if convenient (and in mode MODE if that's convenient). */
static rtx static rtx
expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode) expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
{ {
if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
{ {
tree result = fold_builtin_strstr (arglist); tree result = fold_builtin_strstr (arglist, type);
if (result) if (result)
return expand_expr (result, target, mode, EXPAND_NORMAL); return expand_expr (result, target, mode, EXPAND_NORMAL);
} }
...@@ -2550,11 +2550,11 @@ expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode) ...@@ -2550,11 +2550,11 @@ expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
in TARGET, if convenient (and in mode MODE if that's convenient). */ in TARGET, if convenient (and in mode MODE if that's convenient). */
static rtx static rtx
expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode) expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
{ {
if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
{ {
tree result = fold_builtin_strchr (arglist); tree result = fold_builtin_strchr (arglist, type);
if (result) if (result)
return expand_expr (result, target, mode, EXPAND_NORMAL); return expand_expr (result, target, mode, EXPAND_NORMAL);
...@@ -2568,11 +2568,11 @@ expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode) ...@@ -2568,11 +2568,11 @@ expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
in TARGET, if convenient (and in mode MODE if that's convenient). */ in TARGET, if convenient (and in mode MODE if that's convenient). */
static rtx static rtx
expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode) expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
{ {
if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
{ {
tree result = fold_builtin_strrchr (arglist); tree result = fold_builtin_strrchr (arglist, type);
if (result) if (result)
return expand_expr (result, target, mode, EXPAND_NORMAL); return expand_expr (result, target, mode, EXPAND_NORMAL);
} }
...@@ -2584,11 +2584,11 @@ expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode) ...@@ -2584,11 +2584,11 @@ expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
in TARGET, if convenient (and in mode MODE if that's convenient). */ in TARGET, if convenient (and in mode MODE if that's convenient). */
static rtx static rtx
expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode) expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
{ {
if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
{ {
tree result = fold_builtin_strpbrk (arglist); tree result = fold_builtin_strpbrk (arglist, type);
if (result) if (result)
return expand_expr (result, target, mode, EXPAND_NORMAL); return expand_expr (result, target, mode, EXPAND_NORMAL);
} }
...@@ -5482,27 +5482,27 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, ...@@ -5482,27 +5482,27 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
break; break;
case BUILT_IN_STRSTR: case BUILT_IN_STRSTR:
target = expand_builtin_strstr (arglist, target, mode); target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
if (target) if (target)
return target; return target;
break; break;
case BUILT_IN_STRPBRK: case BUILT_IN_STRPBRK:
target = expand_builtin_strpbrk (arglist, target, mode); target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
if (target) if (target)
return target; return target;
break; break;
case BUILT_IN_INDEX: case BUILT_IN_INDEX:
case BUILT_IN_STRCHR: case BUILT_IN_STRCHR:
target = expand_builtin_strchr (arglist, target, mode); target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
if (target) if (target)
return target; return target;
break; break;
case BUILT_IN_RINDEX: case BUILT_IN_RINDEX:
case BUILT_IN_STRRCHR: case BUILT_IN_STRRCHR:
target = expand_builtin_strrchr (arglist, target, mode); target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
if (target) if (target)
return target; return target;
break; break;
...@@ -7856,7 +7856,7 @@ fold_builtin_1 (tree exp, bool ignore) ...@@ -7856,7 +7856,7 @@ fold_builtin_1 (tree exp, bool ignore)
return fold_builtin_fputs (arglist, ignore, true, NULL_TREE); return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
case BUILT_IN_STRSTR: case BUILT_IN_STRSTR:
return fold_builtin_strstr (arglist); return fold_builtin_strstr (arglist, type);
case BUILT_IN_STRCAT: case BUILT_IN_STRCAT:
return fold_builtin_strcat (arglist); return fold_builtin_strcat (arglist);
...@@ -7872,11 +7872,11 @@ fold_builtin_1 (tree exp, bool ignore) ...@@ -7872,11 +7872,11 @@ fold_builtin_1 (tree exp, bool ignore)
case BUILT_IN_STRCHR: case BUILT_IN_STRCHR:
case BUILT_IN_INDEX: case BUILT_IN_INDEX:
return fold_builtin_strchr (arglist); return fold_builtin_strchr (arglist, type);
case BUILT_IN_STRRCHR: case BUILT_IN_STRRCHR:
case BUILT_IN_RINDEX: case BUILT_IN_RINDEX:
return fold_builtin_strrchr (arglist); return fold_builtin_strrchr (arglist, type);
case BUILT_IN_STRCPY: case BUILT_IN_STRCPY:
return fold_builtin_strcpy (exp, NULL_TREE); return fold_builtin_strcpy (exp, NULL_TREE);
...@@ -7891,7 +7891,7 @@ fold_builtin_1 (tree exp, bool ignore) ...@@ -7891,7 +7891,7 @@ fold_builtin_1 (tree exp, bool ignore)
return fold_builtin_strncmp (arglist); return fold_builtin_strncmp (arglist);
case BUILT_IN_STRPBRK: case BUILT_IN_STRPBRK:
return fold_builtin_strpbrk (arglist); return fold_builtin_strpbrk (arglist, type);
case BUILT_IN_BCMP: case BUILT_IN_BCMP:
case BUILT_IN_MEMCMP: case BUILT_IN_MEMCMP:
...@@ -8326,7 +8326,7 @@ readonly_data_expr (tree exp) ...@@ -8326,7 +8326,7 @@ readonly_data_expr (tree exp)
form of the builtin function call. */ form of the builtin function call. */
static tree static tree
fold_builtin_strstr (tree arglist) fold_builtin_strstr (tree arglist, tree type)
{ {
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
return 0; return 0;
...@@ -8344,13 +8344,15 @@ fold_builtin_strstr (tree arglist) ...@@ -8344,13 +8344,15 @@ fold_builtin_strstr (tree arglist)
if (p1 != NULL) if (p1 != NULL)
{ {
const char *r = strstr (p1, p2); const char *r = strstr (p1, p2);
tree tem;
if (r == NULL) if (r == NULL)
return build_int_cst (TREE_TYPE (s1), 0); return build_int_cst (TREE_TYPE (s1), 0);
/* Return an offset into the constant string argument. */ /* Return an offset into the constant string argument. */
return fold (build2 (PLUS_EXPR, TREE_TYPE (s1), tem = fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
s1, build_int_cst (TREE_TYPE (s1), r - p1))); s1, build_int_cst (TREE_TYPE (s1), r - p1)));
return fold_convert (type, tem);
} }
if (p2[0] == '\0') if (p2[0] == '\0')
...@@ -8390,7 +8392,7 @@ fold_builtin_strstr (tree arglist) ...@@ -8390,7 +8392,7 @@ fold_builtin_strstr (tree arglist)
form of the builtin function call. */ form of the builtin function call. */
static tree static tree
fold_builtin_strchr (tree arglist) fold_builtin_strchr (tree arglist, tree type)
{ {
if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
return 0; return 0;
...@@ -8407,6 +8409,7 @@ fold_builtin_strchr (tree arglist) ...@@ -8407,6 +8409,7 @@ fold_builtin_strchr (tree arglist)
{ {
char c; char c;
const char *r; const char *r;
tree tem;
if (target_char_cast (s2, &c)) if (target_char_cast (s2, &c))
return 0; return 0;
...@@ -8417,8 +8420,9 @@ fold_builtin_strchr (tree arglist) ...@@ -8417,8 +8420,9 @@ fold_builtin_strchr (tree arglist)
return build_int_cst (TREE_TYPE (s1), 0); return build_int_cst (TREE_TYPE (s1), 0);
/* Return an offset into the constant string argument. */ /* Return an offset into the constant string argument. */
return fold (build2 (PLUS_EXPR, TREE_TYPE (s1), tem = fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
s1, build_int_cst (TREE_TYPE (s1), r - p1))); s1, build_int_cst (TREE_TYPE (s1), r - p1)));
return fold_convert (type, tem);
} }
return 0; return 0;
} }
...@@ -8442,7 +8446,7 @@ fold_builtin_strchr (tree arglist) ...@@ -8442,7 +8446,7 @@ fold_builtin_strchr (tree arglist)
form of the builtin function call. */ form of the builtin function call. */
static tree static tree
fold_builtin_strrchr (tree arglist) fold_builtin_strrchr (tree arglist, tree type)
{ {
if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
return 0; return 0;
...@@ -8460,6 +8464,7 @@ fold_builtin_strrchr (tree arglist) ...@@ -8460,6 +8464,7 @@ fold_builtin_strrchr (tree arglist)
{ {
char c; char c;
const char *r; const char *r;
tree tem;
if (target_char_cast (s2, &c)) if (target_char_cast (s2, &c))
return 0; return 0;
...@@ -8470,8 +8475,9 @@ fold_builtin_strrchr (tree arglist) ...@@ -8470,8 +8475,9 @@ fold_builtin_strrchr (tree arglist)
return build_int_cst (TREE_TYPE (s1), 0); return build_int_cst (TREE_TYPE (s1), 0);
/* Return an offset into the constant string argument. */ /* Return an offset into the constant string argument. */
return fold (build2 (PLUS_EXPR, TREE_TYPE (s1), tem = fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
s1, build_int_cst (TREE_TYPE (s1), r - p1))); s1, build_int_cst (TREE_TYPE (s1), r - p1)));
return fold_convert (type, tem);
} }
if (! integer_zerop (s2)) if (! integer_zerop (s2))
...@@ -8504,7 +8510,7 @@ fold_builtin_strrchr (tree arglist) ...@@ -8504,7 +8510,7 @@ fold_builtin_strrchr (tree arglist)
form of the builtin function call. */ form of the builtin function call. */
static tree static tree
fold_builtin_strpbrk (tree arglist) fold_builtin_strpbrk (tree arglist, tree type)
{ {
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
return 0; return 0;
...@@ -8522,13 +8528,15 @@ fold_builtin_strpbrk (tree arglist) ...@@ -8522,13 +8528,15 @@ fold_builtin_strpbrk (tree arglist)
if (p1 != NULL) if (p1 != NULL)
{ {
const char *r = strpbrk (p1, p2); const char *r = strpbrk (p1, p2);
tree tem;
if (r == NULL) if (r == NULL)
return build_int_cst (TREE_TYPE (s1), 0); return build_int_cst (TREE_TYPE (s1), 0);
/* Return an offset into the constant string argument. */ /* Return an offset into the constant string argument. */
return fold (build2 (PLUS_EXPR, TREE_TYPE (s1), tem = fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
s1, build_int_cst (TREE_TYPE (s1), r - p1))); s1, build_int_cst (TREE_TYPE (s1), r - p1)));
return fold_convert (type, tem);
} }
if (p2[0] == '\0') if (p2[0] == '\0')
......
2005-02-16 Kazu Hirata <kazu@cs.umass.edu>
PR tree-optimization/19967
* gcc.dg/pr19967.c: New.
2005-02-16 Jakub Jelinek <jakub@redhat.com> 2005-02-16 Jakub Jelinek <jakub@redhat.com>
PR middle-end/19857 PR middle-end/19857
......
/* PR middle-end/19967
These functions mentioned below are supposed to return char *.
However, fold_builtin_... had bugs that caused the return types to
be const char *. */
/* { dg-do compile } */
/* { dg-options "-pedantic" } */
char *strchr(const char *, int);
char *strrchr(const char *, int);
char *index(const char *, int);
char *rindex(const char *, int);
char *strpbrk(const char *, const char *);
char *strstr(const char *, const char *);
char *p;
void
f (void)
{
p = strchr(__func__, 'f');
p = strrchr(__func__, 'f');
p = index(__func__, 'f');
p = rindex(__func__, 'f');
p = strpbrk(__func__, "f");
p = strstr(__func__, "f");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment