aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-01-23 11:37:02 +0100
committerMartin Sebor <msebor@redhat.com>2020-01-23 11:37:02 +0100
commit8a990ffafaaa18981c6e91d4ed88f05ed74c5f3f (patch)
tree6f5fb53b4e87c5473a3c80a390e87440b1074396
parent0ed442a40f912b09297359ee3675c819c073208f (diff)
downloadgcc-8a990ffafaaa18981c6e91d4ed88f05ed74c5f3f.zip
gcc-8a990ffafaaa18981c6e91d4ed88f05ed74c5f3f.tar.gz
gcc-8a990ffafaaa18981c6e91d4ed88f05ed74c5f3f.tar.bz2
PR c/84919 - bogus -Wrestrict on sprintf %p with destination as argument
gcc/c-family/ChangeLog: PR c/84919 * c-common.c (check_function_arguments): Avoid overlap checking of sprintf functions. gcc/testsuite/ChangeLog: PR c/84919 * gcc.dg/Wrestrict-20.c: New test.
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-common.c22
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/Wrestrict-20.c41
4 files changed, 72 insertions, 2 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 89a66bd..0b9c604 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2020-01-23 Martin Sebor <msebor@redhat.com>
+
+ PR c/84919
+ * c-common.c (check_function_arguments): Avoid overlap checking
+ of sprintf functions.
+
2020-01-22 Jason Merrill <jason@redhat.com>
PR testsuite/93391 - PR 40752 test fails with unsigned plain char.
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 774e29b..7e2dfb3 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -5729,8 +5729,26 @@ check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype,
if (warn_format)
check_function_sentinel (fntype, nargs, argarray);
- if (warn_restrict)
- warned_p |= check_function_restrict (fndecl, fntype, nargs, argarray);
+ if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
+ {
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_SPRINTF:
+ case BUILT_IN_SPRINTF_CHK:
+ case BUILT_IN_SNPRINTF:
+ case BUILT_IN_SNPRINTF_CHK:
+ /* Let the sprintf pass handle these. */
+ return warned_p;
+
+ default:
+ break;
+ }
+ }
+
+ /* check_function_restrict sets the DECL_READ_P for arguments
+ so it must be called unconditionally. */
+ warned_p |= check_function_restrict (fndecl, fntype, nargs, argarray);
+
return warned_p;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d23b3d1..22c172f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-01-23 Martin Sebor <msebor@redhat.com>
+
+ PR c/84919
+ * gcc.dg/Wrestrict-20.c: New test.
+
2020-01-23 Richard Sandiford <richard.sandiford@arm.com>
* g++.target/aarch64/sve/acle/general-c++/whilele_1.C: Skip for ILP32.
diff --git a/gcc/testsuite/gcc.dg/Wrestrict-20.c b/gcc/testsuite/gcc.dg/Wrestrict-20.c
new file mode 100644
index 0000000..9826e7f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wrestrict-20.c
@@ -0,0 +1,41 @@
+/* PR c/84919 - bogus -Wrestrict on sprintf %p with destination as argument
+ { dg-do compile }
+ -O2 isn't strictly necessary but setting also verifies that the sprintf/
+ strlen pass doesn't warn with non-constant arguments.
+ { dg-options "-O2 -Wall" } */
+
+extern int sprintf (char* restrict, const char* restrict, ...);
+extern int snprintf (char* restrict, __SIZE_TYPE__, const char* restrict, ...);
+
+char a[32];
+
+void test_warn (char *p)
+{
+ a[0] = 0;
+ sprintf (a, "a=%s", a); /* { dg-warning "-Wrestrict" } */
+
+ p = a;
+ char *q = p + 1;
+ sprintf (p, "a=%s", q); /* { dg-warning "-Wrestrict" } */
+}
+
+void test_nowarn_front_end (char *d)
+{
+ sprintf (d, "%p", d);
+ snprintf (d, 32, "%p", d);
+
+ sprintf (a, "p=%p", a);
+ snprintf (a, sizeof a, "%p", a);
+}
+
+void test_nowarn_sprintf_pass (char *d)
+{
+ char *q = d;
+
+ sprintf (d, "p=%p", q);
+ snprintf (d, 32, "p=%p", q);
+
+ q = a;
+ sprintf (a, "a=%p", q);
+ snprintf (a, sizeof a, "a=%p", q);
+}