PR middle-end/85359 - duplicate -Wstringop-overflow for a strcmp call with a nonstring pointer
gcc/ChangeLog: PR middle-end/85359 * builtins.c (expand_builtin_strcpy): Call maybe_warn_nonstring_arg only when expasion succeeds. (expand_builtin_strcmp): Same. (expand_builtin_strncmp): Same. gcc/testsuite/ChangeLog: PR middle-end/85359 * gcc.dg/attr-nonstring.c: New test. From-SVN: r260550
This commit is contained in:
parent
aab778d382
commit
36537a1c41
5 changed files with 161 additions and 12 deletions
|
@ -24,6 +24,14 @@
|
|||
|
||||
* config/aarch64/aarch64.md (*ashift<mode>_extv_bfiz): New pattern.
|
||||
|
||||
2018-05-22 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR middle-end/85359
|
||||
* builtins.c (expand_builtin_strcpy): Call maybe_warn_nonstring_arg
|
||||
only when expasion succeeds.
|
||||
(expand_builtin_strcmp): Same.
|
||||
(expand_builtin_strncmp): Same.
|
||||
|
||||
2018-05-22 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
* calls.c (maybe_warn_nonstring_arg): Fix a typo in a comment.
|
||||
|
|
|
@ -3783,7 +3783,17 @@ expand_builtin_strcpy (tree exp, rtx target)
|
|||
src, destsize);
|
||||
}
|
||||
|
||||
return expand_builtin_strcpy_args (dest, src, target);
|
||||
if (rtx ret = expand_builtin_strcpy_args (dest, src, 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);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
/* Helper function to do the actual work for expand_builtin_strcpy. The
|
||||
|
@ -4576,14 +4586,14 @@ 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)
|
||||
{
|
||||
/* 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. */
|
||||
maybe_warn_nonstring_arg (fndecl, exp);
|
||||
|
||||
/* Return the value in the proper mode for this function. */
|
||||
machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
|
||||
if (GET_MODE (result) == mode)
|
||||
|
@ -4680,14 +4690,14 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
|
|||
arg2_rtx, TREE_TYPE (len), arg3_rtx,
|
||||
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)
|
||||
{
|
||||
/* 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. */
|
||||
maybe_warn_nonstring_arg (fndecl, exp);
|
||||
|
||||
/* Return the value in the proper mode for this function. */
|
||||
mode = TYPE_MODE (TREE_TYPE (exp));
|
||||
if (GET_MODE (result) == mode)
|
||||
|
|
|
@ -1671,7 +1671,10 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
|
|||
/* Determine the range of the bound argument (if specified). */
|
||||
tree bndrng[2] = { NULL_TREE, NULL_TREE };
|
||||
if (bound)
|
||||
get_size_range (bound, bndrng);
|
||||
{
|
||||
STRIP_NOPS (bound);
|
||||
get_size_range (bound, bndrng);
|
||||
}
|
||||
|
||||
if (*lenrng)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2018-05-22 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR middle-end/85359
|
||||
* gcc.dg/attr-nonstring.c: New test.
|
||||
|
||||
2018-05-22 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/85345
|
||||
|
|
123
gcc/testsuite/gcc.dg/attr-nonstring.c
Normal file
123
gcc/testsuite/gcc.dg/attr-nonstring.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
/* PR middle-end/85359 - duplicate -Wstringop-overflow for a strcmp call
|
||||
with a nonstring pointer
|
||||
{ dg-do compile }
|
||||
{ dg-options "-O2 -Wall" } */
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
typedef __builtin_va_list va_list;
|
||||
|
||||
int printf (const char*, ...);
|
||||
int puts (const char*);
|
||||
int puts_unlocked (const char*);
|
||||
int sprintf (char*, const char*, ...);
|
||||
int snprintf (char*, size_t, const char*, ...);
|
||||
int vsprintf (char*, const char*, va_list);
|
||||
int vsnprintf (char*, size_t, const char*, va_list);
|
||||
|
||||
int strcmp (const char*, const char*);
|
||||
int strncmp (const char*, const char*, size_t);
|
||||
|
||||
char* stpcpy (char*, const char*);
|
||||
char* stpncpy (char*, const char*, size_t);
|
||||
|
||||
char* strcat (char*, const char*);
|
||||
char* strncat (char*, const char*, size_t);
|
||||
|
||||
char* strcpy (char*, const char*);
|
||||
char* strncpy (char*, const char*, size_t);
|
||||
|
||||
char* strchr (const char*, int);
|
||||
char* strrchr (const char*, int);
|
||||
char* strstr (const char*, const char*);
|
||||
char* strdup (const char*);
|
||||
size_t strlen (const char*);
|
||||
size_t strnlen (const char*, size_t);
|
||||
char* strndup (const char*, size_t);
|
||||
|
||||
#define NONSTRING __attribute__ ((nonstring))
|
||||
|
||||
extern char ns5[5] NONSTRING;
|
||||
|
||||
int strcmp_nonstring_1 (NONSTRING const char *a, const char *b)
|
||||
{
|
||||
/* dg-warning matches one or more instances of the warning so it's
|
||||
no good on its own. Use dg-regexp instead to verify that just
|
||||
one instance of the warning is issued. See gcc.dg/pr64223-1
|
||||
for a different approach. */
|
||||
return strcmp (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .strcmp. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strcmp" } */
|
||||
}
|
||||
|
||||
int strcmp_nonstring_2 (const char *a, NONSTRING const char *b)
|
||||
{
|
||||
return strcmp (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .strcmp. argument 2 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strcmp" } */
|
||||
}
|
||||
|
||||
int strncmp_nonstring_1 (const char *s)
|
||||
{
|
||||
return strncmp (s, ns5, sizeof ns5 + 1); /* { dg-regexp "\[^\n\r\]+: warning: .strncmp. argument 2 declared attribute .nonstring. \[^\n\r\]+ \\\[-Wstringop-overflow=]" "strncmp" } */
|
||||
}
|
||||
|
||||
int strncmp_nonstring_2 (const char *s)
|
||||
{
|
||||
return strncmp (ns5, s, sizeof ns5 + 1); /* { dg-regexp "\[^\n\r\]+: warning: .strncmp. argument 1 declared attribute .nonstring. \[^\n\r\]+ \\\[-Wstringop-overflow=]" "strncmp" } */
|
||||
}
|
||||
|
||||
char* stpcpy_nonstring (char *d, NONSTRING const char *s)
|
||||
{
|
||||
return stpcpy (d, s); /* { dg-regexp "\[^\n\r\]+: warning: .stpcpy. argument 2 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "stpcpy" } */
|
||||
}
|
||||
|
||||
char* stpncpy_nonstring (char *d)
|
||||
{
|
||||
return stpncpy (d, ns5, sizeof ns5 + 1); /* { dg-regexp "\[^\n\r\]+: warning: .stpncpy. argument 2 declared attribute .nonstring. \[^\n\r\]+ \\\[-Wstringop-overflow=]" "stpncpy" } */
|
||||
}
|
||||
|
||||
char* strchr_nonstring (NONSTRING const char *s, int c)
|
||||
{
|
||||
return strchr (s, c); /* { dg-regexp "\[^\n\r\]+: warning: .strchr. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strchr" } */
|
||||
}
|
||||
|
||||
char* strrchr_nonstring (NONSTRING const char *s, int c)
|
||||
{
|
||||
return strrchr (s, c); /* { dg-regexp "\[^\n\r\]+: warning: .strrchr. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strrchr" } */
|
||||
}
|
||||
|
||||
char* strcpy_nonstring (char *d, NONSTRING const char *s)
|
||||
{
|
||||
return strcpy (d, s); /* { dg-regexp "\[^\n\r\]+: warning: .strcpy. argument 2 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strcpy" } */
|
||||
}
|
||||
|
||||
char* strncpy_nonstring (char *d)
|
||||
{
|
||||
return strncpy (d, ns5, sizeof ns5 + 1); /* { dg-regexp "\[^\n\r\]+: warning: .strncpy. argument 2 declared attribute .nonstring. \[^\n\r\]+ \\\[-Wstringop-overflow=]" "strncpy" } */
|
||||
}
|
||||
|
||||
char* strstr_nonstring_1 (NONSTRING const char *a, const char *b)
|
||||
{
|
||||
return strstr (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .strstr. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strstr" } */
|
||||
}
|
||||
|
||||
char* strstr_nonstring_2 (const char *a, NONSTRING const char *b)
|
||||
{
|
||||
return strstr (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .strstr. argument 2 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strstr" } */
|
||||
}
|
||||
|
||||
char* stdup_nonstring (NONSTRING const char *s)
|
||||
{
|
||||
return strdup (s); /* { dg-regexp "\[^\n\r\]+: warning: .strdup. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strdup" } */
|
||||
}
|
||||
|
||||
size_t strlen_nonstring (NONSTRING const char *s)
|
||||
{
|
||||
return strlen (s); /* { dg-regexp "\[^\n\r\]+: warning: .strlen. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strlen" } */
|
||||
}
|
||||
|
||||
int printf_nonstring (NONSTRING const char *s)
|
||||
{
|
||||
return printf (s); /* { dg-regexp "\[^\n\r\]+: warning: .printf. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "printf" } */
|
||||
}
|
||||
|
||||
int sprintf_nonstring_2 (char *d, NONSTRING const char *s)
|
||||
{
|
||||
return sprintf (d, s); /* { dg-regexp "\[^\n\r\]+: warning: .sprintf. argument 2 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "sprintf" } */
|
||||
}
|
Loading…
Add table
Reference in a new issue