Commit 16155777 by Martin Sebor Committed by Martin Sebor

PR testsuite/83131 - c-c++/common/attr-nonstring-3 failure for strcmp tests on PowerPC

gcc/ChangeLog:

	PR testsuite/83131
	* builtins.c (expand_builtin_strlen): Use get_callee_fndecl.
	(expand_builtin_strcmp): Call maybe_warn_nonstring_arg.	
	(expand_builtin_strncmp): Same.

gcc/testsuite/ChangeLog:

	PR testsuite/83131
	* c-c++-common/attr-nonstring-4.c: New test.

From-SVN: r255898
parent 35c4515b
2017-12-20 Martin Sebor <msebor@redhat.com>
PR testsuite/83131
* builtins.c (expand_builtin_strlen): Use get_callee_fndecl.
(expand_builtin_strcmp): Call maybe_warn_nonstring_arg.
(expand_builtin_strncmp): Same.
2017-12-20 Alexandre Oliva <aoliva@redhat.com> 2017-12-20 Alexandre Oliva <aoliva@redhat.com>
PR bootstrap/83396 PR bootstrap/83396
...@@ -2829,8 +2829,7 @@ expand_builtin_strlen (tree exp, rtx target, ...@@ -2829,8 +2829,7 @@ expand_builtin_strlen (tree exp, rtx target,
{ {
if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
return NULL_RTX; return NULL_RTX;
else
{
struct expand_operand ops[4]; struct expand_operand ops[4];
rtx pat; rtx pat;
tree len; tree len;
...@@ -2893,7 +2892,7 @@ expand_builtin_strlen (tree exp, rtx target, ...@@ -2893,7 +2892,7 @@ expand_builtin_strlen (tree exp, rtx target,
/* Check to see if the argument was declared attribute nonstring /* Check to see if the argument was declared attribute nonstring
and if so, issue a warning since at this point it's not known and if so, issue a warning since at this point it's not known
to be nul-terminated. */ to be nul-terminated. */
maybe_warn_nonstring_arg (TREE_OPERAND (CALL_EXPR_FN (exp), 0), exp); maybe_warn_nonstring_arg (get_callee_fndecl (exp), exp);
/* Now that we are assured of success, expand the source. */ /* Now that we are assured of success, expand the source. */
start_sequence (); start_sequence ();
...@@ -2924,7 +2923,6 @@ expand_builtin_strlen (tree exp, rtx target, ...@@ -2924,7 +2923,6 @@ expand_builtin_strlen (tree exp, rtx target,
target = convert_to_mode (target_mode, ops[0].value, 0); target = convert_to_mode (target_mode, ops[0].value, 0);
return target; return target;
}
} }
/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
...@@ -4485,13 +4483,11 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target) ...@@ -4485,13 +4483,11 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
insn_code cmpstr_icode = direct_optab_handler (cmpstr_optab, SImode); insn_code cmpstr_icode = direct_optab_handler (cmpstr_optab, SImode);
insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode); insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode);
if (cmpstr_icode != CODE_FOR_nothing || cmpstrn_icode != CODE_FOR_nothing) if (cmpstr_icode == CODE_FOR_nothing && cmpstrn_icode == CODE_FOR_nothing)
{ return NULL_RTX;
rtx arg1_rtx, arg2_rtx;
tree fndecl, fn;
tree arg1 = CALL_EXPR_ARG (exp, 0); tree arg1 = CALL_EXPR_ARG (exp, 0);
tree arg2 = CALL_EXPR_ARG (exp, 1); tree arg2 = CALL_EXPR_ARG (exp, 1);
rtx result = NULL_RTX;
unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
...@@ -4504,9 +4500,10 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target) ...@@ -4504,9 +4500,10 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
arg1 = builtin_save_expr (arg1); arg1 = builtin_save_expr (arg1);
arg2 = builtin_save_expr (arg2); arg2 = builtin_save_expr (arg2);
arg1_rtx = get_memory_rtx (arg1, NULL); rtx arg1_rtx = get_memory_rtx (arg1, NULL);
arg2_rtx = get_memory_rtx (arg2, NULL); rtx arg2_rtx = get_memory_rtx (arg2, NULL);
rtx result = NULL_RTX;
/* Try to call cmpstrsi. */ /* Try to call cmpstrsi. */
if (cmpstr_icode != CODE_FOR_nothing) if (cmpstr_icode != CODE_FOR_nothing)
result = expand_cmpstr (cmpstr_icode, target, arg1_rtx, arg2_rtx, result = expand_cmpstr (cmpstr_icode, target, arg1_rtx, arg2_rtx,
...@@ -4560,6 +4557,12 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target) ...@@ -4560,6 +4557,12 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
} }
} }
/* Check to see if the argument was declared attribute nonstring
and if so, issue a warning since at this point it's not known
to be nul-terminated. */
tree fndecl = get_callee_fndecl (exp);
maybe_warn_nonstring_arg (fndecl, exp);
if (result) if (result)
{ {
/* Return the value in the proper mode for this function. */ /* Return the value in the proper mode for this function. */
...@@ -4574,13 +4577,10 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target) ...@@ -4574,13 +4577,10 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
/* Expand the library call ourselves using a stabilized argument /* Expand the library call ourselves using a stabilized argument
list to avoid re-evaluating the function's arguments twice. */ list to avoid re-evaluating the function's arguments twice. */
fndecl = get_callee_fndecl (exp); tree fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 2, arg1, arg2);
fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 2, arg1, arg2);
gcc_assert (TREE_CODE (fn) == CALL_EXPR); gcc_assert (TREE_CODE (fn) == CALL_EXPR);
CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
return expand_call (fn, target, target == const0_rtx); return expand_call (fn, target, target == const0_rtx);
}
return NULL_RTX;
} }
/* Expand expression EXP, which is a call to the strncmp builtin. Return /* Expand expression EXP, which is a call to the strncmp builtin. Return
...@@ -4591,8 +4591,6 @@ static rtx ...@@ -4591,8 +4591,6 @@ static rtx
expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target, expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
ATTRIBUTE_UNUSED machine_mode mode) ATTRIBUTE_UNUSED machine_mode mode)
{ {
location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
if (!validate_arglist (exp, if (!validate_arglist (exp,
POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
return NULL_RTX; return NULL_RTX;
...@@ -4601,12 +4599,11 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target, ...@@ -4601,12 +4599,11 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
lengths, and it doesn't have side effects, then emit cmpstrnsi lengths, and it doesn't have side effects, then emit cmpstrnsi
using length MIN(strlen(string)+1, arg3). */ using length MIN(strlen(string)+1, arg3). */
insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode); insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode);
if (cmpstrn_icode != CODE_FOR_nothing) if (cmpstrn_icode == CODE_FOR_nothing)
{ return NULL_RTX;
tree len, len1, len2, len3;
rtx arg1_rtx, arg2_rtx, arg3_rtx; tree len;
rtx result;
tree fndecl, fn;
tree arg1 = CALL_EXPR_ARG (exp, 0); tree arg1 = CALL_EXPR_ARG (exp, 0);
tree arg2 = CALL_EXPR_ARG (exp, 1); tree arg2 = CALL_EXPR_ARG (exp, 1);
tree arg3 = CALL_EXPR_ARG (exp, 2); tree arg3 = CALL_EXPR_ARG (exp, 2);
...@@ -4614,15 +4611,17 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target, ...@@ -4614,15 +4611,17 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
len1 = c_strlen (arg1, 1); tree len1 = c_strlen (arg1, 1);
len2 = c_strlen (arg2, 1); tree len2 = c_strlen (arg2, 1);
location_t loc = EXPR_LOCATION (exp);
if (len1) if (len1)
len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1); len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1);
if (len2) if (len2)
len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2); len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2);
len3 = fold_convert_loc (loc, sizetype, arg3); tree len3 = fold_convert_loc (loc, sizetype, arg3);
/* If we don't have a constant length for the first, use the length /* If we don't have a constant length for the first, use the length
of the second, if we know it. If neither string is constant length, of the second, if we know it. If neither string is constant length,
...@@ -4655,12 +4654,19 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target, ...@@ -4655,12 +4654,19 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
The actual new length parameter will be MIN(len,arg3) in this case. */ The actual new length parameter will be MIN(len,arg3) in this case. */
if (len != len3) if (len != len3)
len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len, len3); len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len, len3);
arg1_rtx = get_memory_rtx (arg1, len); rtx arg1_rtx = get_memory_rtx (arg1, len);
arg2_rtx = get_memory_rtx (arg2, len); rtx arg2_rtx = get_memory_rtx (arg2, len);
arg3_rtx = expand_normal (len); rtx arg3_rtx = expand_normal (len);
result = expand_cmpstrn_or_cmpmem (cmpstrn_icode, target, arg1_rtx, rtx result = expand_cmpstrn_or_cmpmem (cmpstrn_icode, target, arg1_rtx,
arg2_rtx, TREE_TYPE (len), arg3_rtx, arg2_rtx, TREE_TYPE (len), arg3_rtx,
MIN (arg1_align, arg2_align)); MIN (arg1_align, arg2_align));
/* Check to see if the argument was declared attribute nonstring
and if so, issue a warning since at this point it's not known
to be nul-terminated. */
tree fndecl = get_callee_fndecl (exp);
maybe_warn_nonstring_arg (fndecl, exp);
if (result) if (result)
{ {
/* Return the value in the proper mode for this function. */ /* Return the value in the proper mode for this function. */
...@@ -4675,14 +4681,10 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target, ...@@ -4675,14 +4681,10 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
/* Expand the library call ourselves using a stabilized argument /* Expand the library call ourselves using a stabilized argument
list to avoid re-evaluating the function's arguments twice. */ list to avoid re-evaluating the function's arguments twice. */
fndecl = get_callee_fndecl (exp); tree fn = build_call_nofold_loc (loc, fndecl, 3, arg1, arg2, len);
fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 3,
arg1, arg2, len);
gcc_assert (TREE_CODE (fn) == CALL_EXPR); gcc_assert (TREE_CODE (fn) == CALL_EXPR);
CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
return expand_call (fn, target, target == const0_rtx); return expand_call (fn, target, target == const0_rtx);
}
return NULL_RTX;
} }
/* Expand a call to __builtin_saveregs, generating the result in TARGET, /* Expand a call to __builtin_saveregs, generating the result in TARGET,
......
2017-12-20 Martin Sebor <msebor@redhat.com>
PR testsuite/83131
* c-c++-common/attr-nonstring-4.c: New test.
2017-12-20 Richard Sandiford <richard.sandiford@linaro.org> 2017-12-20 Richard Sandiford <richard.sandiford@linaro.org>
* gcc.dg/plugin/poly-int-tests.h (test_nonpoly_multiple_p): New * gcc.dg/plugin/poly-int-tests.h (test_nonpoly_multiple_p): New
......
/* PR middle-end/83131 - c-c++/common/attr-nonstring-3 failure for strcmp
tests on PowerPC
{ dg-do compile }
{ dg-options "-O2 -Wstringop-overflow -ftrack-macro-expansion=0" } */
#if __cplusplus
extern "C" {
#endif
typedef __SIZE_TYPE__ size_t;
extern int strcmp (const char*, const char*);
extern int strncmp (const char*, const char*, size_t);
#if __cplusplus
} /* extern "C" */
#endif
extern char arx[] __attribute__ ((nonstring));
extern char ar5[5] __attribute__ ((nonstring));
extern char str[];
enum { N = sizeof ar5 };
enum { X = sizeof ar5 + 1 };
int warn_strcmp_cst_1 (void)
{
return strcmp ("bar", arx); /* { dg-warning "argument 2 declared attribute .nonstring." } */
}
int warn_strcmp_cst_2 (void)
{
return strcmp (arx, "foo"); /* { dg-warning "argument 1 declared attribute .nonstring." } */
}
int warn_strncmp_cst_1 (void)
{
return strncmp ("bar", ar5, X); /* { dg-warning "argument 2 declared attribute .nonstring." } */
}
int warn_strncmp_cst_2 (void)
{
return strncmp (ar5, "foo", X); /* { dg-warning "argument 1 declared attribute .nonstring." } */
}
int nowarn_strncmp_cst_1 (void)
{
return strncmp ("bar", ar5, N);
}
int nowarn_strncmp_cst_2 (void)
{
return strncmp (ar5, "foo", N);
}
int warn_strncmp_var_1 (void)
{
return strncmp (str, ar5, X); /* { dg-warning "argument 2 declared attribute .nonstring." } */
}
int warn_strncmp_var_2 (void)
{
return strncmp (ar5, str, X); /* { dg-warning "argument 1 declared attribute .nonstring." } */
}
int nowarn_strncmp_var_1 (void)
{
return strncmp (str, ar5, N);
}
int nowarn_strncmp_var_2 (void)
{
return strncmp (ar5, str, N);
}
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