aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2018-01-03 23:41:32 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2018-01-03 16:41:32 -0700
commitcf3fc0e8ac5a9b65bb213f979a4030e43243a5fc (patch)
tree1798e91130802e29c9e570a63e5f6dc7d6080c69 /gcc
parent2438cb6a1dd5f983314b21988b915699c01a2e28 (diff)
downloadgcc-cf3fc0e8ac5a9b65bb213f979a4030e43243a5fc.zip
gcc-cf3fc0e8ac5a9b65bb213f979a4030e43243a5fc.tar.gz
gcc-cf3fc0e8ac5a9b65bb213f979a4030e43243a5fc.tar.bz2
PR tree-optimization/83655 - ICE on an invalid call to memcpy declared with no prototype
gcc/testsuite/ChangeLog: PR tree-optimization/83655 * gcc.dg/Wrestrict-5.c: New test. * c-c++-common/builtins.c: New test. gcc/ChangeLog: PR tree-optimization/83655 * gimple-ssa-warn-restrict.c (wrestrict_dom_walker::check_call): Avoid checking calls with invalid arguments. From-SVN: r256218
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gimple-ssa-warn-restrict.c13
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/c-c++-common/builtins.c193
-rw-r--r--gcc/testsuite/gcc.dg/Wrestrict-5.c43
5 files changed, 260 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 78c30df..a11d6e3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-01-03 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/83655
+ * gimple-ssa-warn-restrict.c (wrestrict_dom_walker::check_call): Avoid
+ checking calls with invalid arguments.
+
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
* tree-vect-stmts.c (vect_get_store_rhs): New function.
diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c
index 97d2af7..066be1a 100644
--- a/gcc/gimple-ssa-warn-restrict.c
+++ b/gcc/gimple-ssa-warn-restrict.c
@@ -1693,7 +1693,18 @@ wrestrict_dom_walker::check_call (gcall *call)
/* DST and SRC can be null for a call with an insufficient number
of arguments to a built-in function declared without a protype. */
- if (!dst || !src || check_bounds_or_overlap (call, dst, src, dstwr, NULL_TREE))
+ if (!dst || !src)
+ return;
+
+ /* DST, SRC, or DSTWR can also have the wrong type in a call to
+ a function declared without a prototype. Avoid checking such
+ invalid calls. */
+ if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
+ || TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE
+ || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
+ return;
+
+ if (check_bounds_or_overlap (call, dst, src, dstwr, NULL_TREE))
return;
/* Avoid diagnosing the call again. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a5779f7..53900981 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2018-01-03 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/83655
+ * gcc.dg/Wrestrict-5.c: New test.
+ * c-c++-common/builtins.c: New test.
+
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
diff --git a/gcc/testsuite/c-c++-common/builtins.c b/gcc/testsuite/c-c++-common/builtins.c
new file mode 100644
index 0000000..673fcad
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/builtins.c
@@ -0,0 +1,193 @@
+/* Test to verify that calls to common built-in functions declared
+ with no prototype do not cause an ICE.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wextra" }
+ { dg-prune-output "warning" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+#if __cplusplus
+extern "C" {
+
+#define NO_PROTO ...
+#else
+#define NO_PROTO /* empty */
+#endif
+
+ /* Character classification built-ins from <ctype.h>. */
+ int isalpha (NO_PROTO);
+ int isalnum (NO_PROTO);
+ int isalpha (NO_PROTO);
+ int iscntrl (NO_PROTO);
+ int isdigit (NO_PROTO);
+ int isgraph (NO_PROTO);
+ int islower (NO_PROTO);
+ int isprint (NO_PROTO);
+ int ispunct (NO_PROTO);
+ int isspace (NO_PROTO);
+ int isupper (NO_PROTO);
+ int isxdigit (NO_PROTO);
+ int tolower (NO_PROTO);
+ int toupper (NO_PROTO);
+
+ /* Memory allocation built-ins from <stdlib.h>. */
+ void* alloca (NO_PROTO);
+ void* aligned_alloc (NO_PROTO);
+ void* calloc (NO_PROTO);
+ void* malloc (NO_PROTO);
+ void* realloc (NO_PROTO);
+
+ /* Raw memory built-ins from <string.h>. */
+ void* memcpy (NO_PROTO);
+ void* memchr (NO_PROTO);
+ void* memmove (NO_PROTO);
+ void* mempcpy (NO_PROTO);
+ void* memset (NO_PROTO);
+
+ /* String built-ins from <string.h>. */
+ char* stpcpy (NO_PROTO);
+ char* stpncpy (NO_PROTO);
+
+ char* strcat (NO_PROTO);
+ char* strcpy (NO_PROTO);
+
+ char* strdup (NO_PROTO);
+ char* strndup (NO_PROTO);
+
+ char* strncat (NO_PROTO);
+ char* strncpy (NO_PROTO);
+
+ size_t strlen (NO_PROTO);
+ size_t strnlen (NO_PROTO);
+
+ char* strchr (NO_PROTO);
+ int strcmp (NO_PROTO);
+ int strncmp (NO_PROTO);
+
+ /* Input/output functions from <stdio.h>. */
+ int puts (NO_PROTO);
+ int fputs (NO_PROTO);
+
+ int scanf (NO_PROTO);
+ int fscanf (NO_PROTO);
+ int sscanf (NO_PROTO);
+ int vfscanf (NO_PROTO);
+ int vsscanf (NO_PROTO);
+
+ int printf (NO_PROTO);
+ int fprintf (NO_PROTO);
+ int sprintf (NO_PROTO);
+
+ int snprintf (NO_PROTO);
+
+ int vprintf (NO_PROTO);
+ int vfprintf (NO_PROTO);
+ int vsprintf (NO_PROTO);
+
+ int vsnprintf (NO_PROTO);
+
+#if __cplusplus
+}
+#endif
+
+
+#define CONCAT(a, b) a ## b
+#define UNIQ_NAME(func, id) CONCAT (test_ ## func ## _, id)
+
+#define TEST_FUNC(func, arglist) \
+ __typeof__ (func arglist) \
+ UNIQ_NAME (func, __COUNTER__) (void) { \
+ return func arglist; \
+ }
+
+#define T1(func) \
+ TEST_FUNC (func, ()); \
+ TEST_FUNC (func, (1)); \
+ TEST_FUNC (func, ("")); \
+ TEST_FUNC (func, ((void*)1)); \
+ TEST_FUNC (func, (iarr)); \
+ TEST_FUNC (func, (function))
+
+#define T2(func) \
+ TEST_FUNC (func, (1, 1)); \
+ TEST_FUNC (func, (1, "")); \
+ TEST_FUNC (func, (1, (void*)1)); \
+ TEST_FUNC (func, (1, iarr)); \
+ TEST_FUNC (func, (1, function))
+
+#define T3(func) \
+ TEST_FUNC (func, (1, 1, 1)); \
+ TEST_FUNC (func, (1, 1, "")); \
+ TEST_FUNC (func, (1, 1, (void*)1)); \
+ TEST_FUNC (func, (1, 1, iarr)); \
+ TEST_FUNC (func, (1, 1, function))
+
+extern int iarr[];
+extern void function (void);
+
+T1 (isalpha);
+T1 (isalnum);
+T1 (isalpha);
+T1 (iscntrl);
+T1 (isdigit);
+T1 (isgraph);
+T1 (islower);
+T1 (isprint);
+T1 (ispunct);
+T1 (isspace);
+T1 (isupper);
+T1 (isxdigit);
+T1 (tolower);
+T1 (toupper);
+
+T1 (alloca);
+T2 (aligned_alloc);
+T2 (malloc);
+T2 (calloc);
+T2 (realloc);
+
+T3 (memcpy);
+T3 (memmove);
+T3 (mempcpy);
+T3 (memset);
+T3 (memchr);
+
+T2 (stpcpy);
+T3 (stpncpy);
+
+T2 (strcat);
+T2 (strcpy);
+
+T1 (strdup);
+T2 (strndup);
+
+T3 (strncat);
+T3 (strncpy);
+
+T2 (strchr);
+T2 (strcmp);
+T3 (strncmp);
+
+T1 (strlen);
+T2 (strnlen);
+
+T1 (puts);
+T2 (fputs);
+
+T1 (scanf);
+T2 (fscanf);
+T2 (sscanf);
+T2 (vfscanf);
+T2 (vsscanf);
+
+T2 (printf);
+T3 (fprintf);
+T3 (sprintf);
+
+T3 (snprintf);
+
+T2 (vprintf);
+T2 (vfprintf);
+T2 (vsprintf);
+
+T3 (vsnprintf);
diff --git a/gcc/testsuite/gcc.dg/Wrestrict-5.c b/gcc/testsuite/gcc.dg/Wrestrict-5.c
new file mode 100644
index 0000000..4912ee5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wrestrict-5.c
@@ -0,0 +1,43 @@
+/* Test to verify that valid calls to common restrict-qualified built-in
+ functions declared with no prototype are checked for overlap, and that
+ invalid calls are ignored.
+ { dg-do compile }
+ { dg-options "-O2 -Wrestrict" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+#if __cplusplus
+extern "C" {
+
+#define NO_PROTO ...
+#else
+#define NO_PROTO /* empty */
+#endif
+
+void* memcpy ();
+char* strncpy ();
+
+#if __cplusplus
+} /* extern "C" */
+#endif
+
+void test_memcpy_warn (char *d)
+{
+ memcpy (d, d + 2, 3); /* { dg-warning "accessing 3 bytes at offsets 0 and 2 overlaps 1 byte at offset 2" } */
+}
+
+void test_memcpy_nowarn (char *d)
+{
+ memcpy (d, d + 2, "");
+}
+
+
+void test_strncpy_warn (char *d)
+{
+ strncpy (d + 1, d + 3, 5); /* { dg-warning "accessing 5 bytes at offsets 1 and 3 overlaps 2 bytes at offset 3" } */
+}
+
+void test_strncpy_nowarn (char *d)
+{
+ strncpy (d + 1, d + 3, "");
+}