This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] avoid duplicate warning for strcmp with a nonstring (PR 85359)
- From: Martin Sebor <msebor at gmail dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 12 Apr 2018 14:52:28 -0600
- Subject: [PATCH] avoid duplicate warning for strcmp with a nonstring (PR 85359)
The attached patch makes a small tweak to avoid issuing a duplicate
warning for calls to strcmp with a nonstring argument. The most
onerous part of this was figuring out how to test for the absence
of duplicate warnings. The "hack" I used (dg-regexp) is in place
until a more straightforward solution becomes available. (David
Malcolm has something planned for GCC 9.)
Martin
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_strcmp): Take care to avoid issuing
a duplicate warning.
gcc/testsuite/ChangeLog:
PR middle-end/85359
* gcc.dg/attr-nonstring.c: New test.
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c (revision 259298)
+++ gcc/builtins.c (working copy)
@@ -4570,14 +4570,15 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED
}
}
- /* 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. Avoid doing this when RESULT is false
+ and let expand_call() do it. */
+ 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)
Index: gcc/testsuite/gcc.dg/attr-nonstring.c
===================================================================
--- gcc/testsuite/gcc.dg/attr-nonstring.c (nonexistent)
+++ gcc/testsuite/gcc.dg/attr-nonstring.c (working copy)
@@ -0,0 +1,58 @@
+/* PR middle-end/85359 - duplicate -Wstringop-overflow for a strcmp call
+ with a nonstring pointer
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+extern char* strchr (const char*, int);
+extern char* strrchr (const char*, int);
+extern char* stpcpy (char*, const char*);
+extern char* strcpy (char*, const char*);
+extern int strcmp (const char*, const char*);
+extern char* strstr (const char*, const char*);
+
+#define NONSTRING __attribute__ ((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=]" } */
+}
+
+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=]" } */
+}
+
+
+char* stpcpy_nonstring (char *a, NONSTRING const char *b)
+{
+ return stpcpy (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .stpcpy. argument 2 declared attribute .nonstring. \\\[-Wstringop-overflow=]" } */
+}
+
+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=]" } */
+}
+
+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=]" } */
+}
+
+char* strcpy_nonstring (char *a, NONSTRING const char *b)
+{
+ return strcpy (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .strcpy. argument 2 declared attribute .nonstring. \\\[-Wstringop-overflow=]" } */
+}
+
+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=]" } */
+}
+
+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=]" } */
+}